PDA

View Full Version : What's with this "static" instance declaration?




BadWolf13
Oct 14, 2010, 06:37 PM
Ok, working though the Core Data Utility Tutorial, and there's a bit of code here that works, but I don't understand it, so I was hoping someone could explain it to me.


static NSManagedObjectModel *mom = nil;

if (mom != nil) {
return mom;
}


What I see is that it's creating an instance of NSManagedObjectModel and assigning it a nil value. Then it's asking if that instance is not equal to nil. How can it ever NOT be nil, if the line directly before the if statement assigns it a nil value? This is what I don't understand. Anyone got any clue?



Catfish_Man
Oct 14, 2010, 06:40 PM
static is what's called a "storage class". It effectively makes that a global variable; initialized to 0 at program startup time, and only one copy ever instead of a new one each time the function is called.

global variables are static by default.

<edit>
That code, by itself, is broken though. It needs to be assigned non-nil *somewhere*. The usual pattern is:

static Foo *bar;
if (bar == nil) {
bar = [[Foo alloc] init];
}
return bar;

</edit>

chown33
Oct 14, 2010, 06:59 PM
The posted code was a fragment. The actual code is not broken, AFAICT. It just inverts the usual idiom so there isn't a big block for the if-nil condition.

http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/CoreDataUtilityTutorial/Articles/08_sourceListings.html

BadWolf13
Oct 14, 2010, 07:42 PM
So the use of the "static" at the beginning of the declaration basically causes the program to ignore the declaration and value assignment if the instance has already been declared?

cubist
Oct 14, 2010, 09:58 PM
Actually, static on a global variable makes it private to that source module. Remember Cocoa is basically C, not C++.

BadWolf13
Oct 14, 2010, 10:20 PM
Actually, static on a global variable makes it private to that source module. Remember Cocoa is basically C, not C++.

Perhaps I should have specified. This code snippet is actually within a method, so if the "static" wasn't there, it would not have been a global.

knightlie
Oct 15, 2010, 07:12 AM
The pattern behind this code is that the managedObjectModel() function is called whenever your program needs a managed object model, but the function will only create mom if it doesn't already exist - it's a Singleton pattern. If the static variable mom were set to nil then the next time managedObjectModel() was called it would recreate mom.

Sydde
Oct 15, 2010, 10:48 AM
Perhaps I should have specified. This code snippet is actually within a method, so if the "static" wasn't there, it would not have been a global.

Correct. Local variables live on the call stack, so they are transient. Static and global variables live in a reserved space at the bottom of the heap, just above constants. Declarations made within a routine or method are variables that cannot be seen outside that routine or method.

If "static" were not there, mom would be a local variable, living on the stack. The "static" part tells the compiler to reserve heap space for mom and initialize it to nil with code placed near where the program starts, not when the routine is called.

BadWolf13
Oct 15, 2010, 12:56 PM
The "static" part tells the compiler to reserve heap space for mom and initialize it to nil with code placed near where the program starts, not when the routine is called.

Wait, I may just be more confused, or I may just get it now. The "static" keyword there causes the compiler to move that line to the beginning of the program instead of at the beginning of the method?

ulbador
Oct 15, 2010, 01:43 PM
Although static variable are sort of global, it basically just means a variable or a method you can call without instantiating the class. Where I have used it the most is in Java, but it's going to be pretty similar in most languages. Take this class:



class TestClass {

public static String MyVar1 = "hello";
public string MyVar2 = "world";

public TestClass() {}

}



In this case, to get at MyVar1, you can just do:

System.out.println(TestClass.MyVar1);

Which would print out "hello". If you tried to do:

System.out.println(TestClass.MyVar2);

You would get a null pointer.

To get at MyVar2, you would actually be required to instantiate the class.

TestClass tc = new TestClass();
System.out.println(tc.MyVar2);

Which prints "world".

Of course, your mileage may vary depending on the language, but as I said, it's going to be largely the same in most high level languages. As someone above mentioned, they can be huge memory hogs, since all static variables and methods for classes have to be allocated in memory when the program begins, not on demand.