Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Static string variable in Objective C on iphone

How to create & access static string in iPhone (objective c)? I declare static NSString *str = @"OldValue" in class A.

If i assign some value to this in class B as str = @"NewValue". This value persists for all methods in class B. But if I access it in class C (after assignment in B) I am getting it as OldValue. Am I missing something? Should i use extern in other classes?

Thanks & Regards, Yogini

like image 816
Yogini Avatar asked Jun 11 '09 09:06

Yogini


People also ask

How do you declare a string in Objective-C?

An NSString uses the @ character: NSString *myNSString = @"test"; If you need to manage the NSString's memory: NSString *myNSString = [NSString stringWithFormat:@"test"]; NSString *myRetainedNSString = [[NSString alloc] initWithFormat:@"test"];

What is a static variable in Objective-C?

In both C and Objective-C, a static variable is a variable that is allocated for the entire lifetime of a program. This is in contrast to automatic variables, whose lifetime exists during a single function call; and dynamically-allocated variables like objects, which can be released from memory when no longer used.

How do you declare a static string?

Note: To create a static member(block, variable, method, nested class), precede its declaration with the keyword static. When a member is declared static, it can be accessed before any objects of its class are created, and without reference to any object.


2 Answers

Update: As of Xcode 8, Objective-C does have class properties. Note, it's mostly syntactic sugar; these properties are not auto-synthesized, so the implementation is basically unchanged from before.

// MyClass.h @interface MyClass : NSObject @property( class, copy ) NSString* str; @end  // MyClass.m #import "MyClass.h"  @implementation MyClass  static NSString* str;  + (NSString*) str  {     return str; }  + (void) setStr:(NSString*)newStr  {     if( str != newStr ) {         str = [newStr copy];     } } @end   // Client code MyClass.str = @"Some String"; NSLog( @"%@", MyClass.str ); // "Some String" 

See WWDC 2016 What's New in LLVM. The class property part starts at around the 5 minute mark.

Original Answer:

Objective-C doesn't have class variables, which is what I think you're looking for. You can kinda fake it with static variables, as you're doing.

I would recommend putting the static NSString in the implementation file of your class, and provide class methods to access/mutate it. Something like this:

// MyClass.h @interface MyClass : NSObject { } + (NSString*)str; + (void)setStr:(NSString*)newStr; @end  // MyClass.m #import "MyClass.h"  static NSString* str;  @implementation MyClass  + (NSString*)str {     return str; }  + (void)setStr:(NSString*)newStr {     if (str != newStr) {         [str release];         str = [newStr copy];     } } @end 
like image 92
zpasternack Avatar answered Sep 21 '22 22:09

zpasternack


Unlike Java, where a static variable is scoped for all instances of a class, static in C means that a variable is accessible only from within the file where it is declared. It allows you to do things like declare a static variable inside a function, which sets the value only the first time through, like this.

One thing you haven't mentioned is the relationship between classes A, B, and C. If they are in an inheritance hierarchy, and you're expecting the static variable to be inherited as in Java, the method described by zpasternack will work.

If the three classes are unrelated, and you just want to access the value declared in A, then extern is a more appropriate way to go. In this case, you want to declare the variable as extern in ClassA.h, then define it in Class.m. As long as ClassB and ClassC import ClassA.h, they will be able to link against the same extern definition.

One fine point is that, instead of using extern by itself, it's more robust to use OBJC_EXPORT, which is defined in objc-api.h and handles compiling under C++ as well. Here's a code sample:

// ClassA.h OBJC_EXPORT NSString* commonString; ...  // ClassA.m NSString* commonString = @"OldValue";  // ClassB.m #import "ClassA.h" ... commonString = @"NewValue"; // Can be inside a function or method 

Of course, using externed variables in this way creates an infamous, much-maligned global variable, which is fragile in that anyone can read or write it, and access is uncontrolled. This is the simple approach, and answers your question about using static vs. extern. However, as a design principle, the encapsulation provided by wrapping the variable with class methods is much safer, albeit more complex. In object-oriented languages, when the effect you're trying to achieve is that of a class-static method, encapsulation is probably the right way to go.

like image 41
Quinn Taylor Avatar answered Sep 21 '22 22:09

Quinn Taylor