« MBS Plugin Advent cal… | Home | Functions in JSON Que… »

Static Variables in Xojo

In Xojo variable declaration somewhere inside a piece of code, you can use the static keyword. Whether you are in an event handler, a menu handler, a method or a global function doesn't matter. Just swap your "var" or "dim" with a "static" and you get a global variable. Instead of allocating memory for the variable on the stack and thus loosing the value on the end of the current code block, the static variable will remember the value. You can easily use it as counter for how often a method is called or for a global dictionary to cache results.

Here is a sample for a method which counts how often it gets invoked:

Sub testCounter() Static counter As Integer counter = counter + 1 System.DebugLog CurrentMethodName+" called already "+counter.ToString+" times." End Sub

Or one for caching:

Function GetPicture(name as string) As Picture Static cache As New Dictionary // lookup whether we have a cached copy Dim pic As Picture = cache.Lookup(name, Nil) If pic = Nil Then // load it and add to cache for next time pic = LoadPictureFromDatabase(name) cache.Value(name) = pic End If Return pic End Function

Now you need to be aware of an issue with these static variables and overloaded methods which existed for at least 5 years: #52943. If two methods have the same name and use the same static variable, you actually only get one:

Sub test() Static n As Integer n = n + 1 System.DebugLog n.ToString+" in "+ CurrentMethodName End Sub
Sub test(s as string) Static n As Integer n = n + 1 System.DebugLog n.ToString+" in "+ CurrentMethodName End Sub

If you call both test and test "hello", you get n set to 2, although each method should have their own n. Depending for whether you like this or not, this may be a great feature or a bug.

Another thing to know is that Xojo keeps a boolean hidden for each static variable. Thus the static variable is implemented by two global variables. One boolean to know whether the static variable is initialized and a second one for the value. If we run "new dictionary" above, the boolean is checked and if it is false, the code to make the new dictionary runs. The boolean is then set to true to avoid it getting overwritten on the next method call. This is not new to me as C++ does it the same way.

Everything you could do with a static variable, could also be done with a global property in a module or a shared property in a class. But since we like to scope variables as narrow as possible to reduce bugs and we love the initialization in the declare line, we tend to use statics a lot. But as soon as you need a second method to access the static like in a ClearCache method, you would make it a shared property again.

05 12 23 - 12:03