0

When you need to initialize a static variable in Java, you can do something like that:

public class MyClass {

  private static Object someStaticObject;
  static {
    // initialize  someStaticObject here
  }
  ...

How can you do the same in Cocoa?

Specifically, here is what I am after: I have an app with a large number of user preferences. I would like to manage all these preferences from one class where all methods are static, as follows:

@implementation Preferences

    +(void)setMotion:(BOOL)isMotion {
      [[NSUserDefaults standardUserDefaults] setBool:isMotion forKey:keyIsMotion];
      [[NSUserDefaults standardUserDefaults] synchronize];
    }

    +(BOOL)isMotion {
      [[NSUserDefaults standardUserDefaults] boolForKey:keyIsMotion];
    }

So that I can access and set my preference easily anywhere in my code with:

[Preferences setMotion:TRUE];  

or

if ([Preferences isMotion]) {
  ...

Given that I plan to have tens of static methods, it would like to have a static variable defaults defined as follows:

NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];

so that my code above could become:

+(void)setMotion:(BOOL)isMotion {
  [defaults setBool:isMotion forKey:keyIsMotion];
  [defaults synchronize];
}

+(BOOL)isMotion {
  [defaults boolForKey:keyIsMotion];
}

However, I am not sure how to accomplish that.

Mark Pope
  • 11,244
  • 10
  • 49
  • 59
double07
  • 2,565
  • 2
  • 22
  • 22
  • See also: [Class variable memory lifecycle in objective-c](http://stackoverflow.com/questions/5839247/class-variable-memory-lifecycle-in-objective-c/5839668#5839668). –  Apr 30 '11 at 22:15

2 Answers2

1

You can override + (void)initialize method on your Objective-C object.

From Apple Docs on NSObject:

The runtime sends initialize to each class in a program exactly one time just before the class, or any class that inherits from it, is sent its first message from within the program. (Thus the method may never be invoked if the class is not used.) The runtime sends the initialize message to classes in a thread-safe manner. Superclasses receive this message before their subclasses.

You can used that method it initialize static ivars and or NSUserDefaults

Black Frog
  • 11,595
  • 1
  • 35
  • 66
0

In short, just declare the static variable in the implementation block of your class's implementation file (but outside of any method). Then provide accessor methods to the static variable, just as you mentioned above.

Read Class Variables for Objective-C and see also this post

Community
  • 1
  • 1
Todd Hopkinson
  • 6,803
  • 5
  • 32
  • 34
  • Actually, one more follow-up question: what would the accessor methods that you refer to gain me here? Accessing the variable directly in my code (i.e. not through a getter) is simpler and just fine in this case, right? – double07 May 01 '11 at 02:06
  • Because by using a method you encapsulate whatever you are doing within that class, and the caller doesn't have to care how you do it and you can change implementation particulars, including variables, without affecting anyone calling those methods. Direct access to variables increases the tendency for changes in the internals of your class to affect those directly accessing it's variables. – Todd Hopkinson May 01 '11 at 14:43
  • Right, but here defaults is a private though, so the benefits of encapsulation seem minimal. I agree that using getters/setters is in general a good idea. Now, follow-up question n.2. Is there a need to release a static object, or will it be released automatically when the application shuts down? If it needs to be released, where would this happen? – double07 May 01 '11 at 18:38
  • But you never know if perhaps you will change the way you store the defaults in the future. Perhaps tomorrow you decide you want to use some other kind of mechanism. If anything outside of the class is dependent upon calling its variables directly, you have to change those as well. But, you are right, you have to balance everything out and if it doesn't make sense to fully encapsulate, quick and dirty might just sometimes be the way to go. – Todd Hopkinson May 03 '11 at 19:12