Initializing a static variable in Objective-C

In the Objective-C class, I want to load only the contents of a text file into NSString once so that it can be used by all instances of this class.

In the Java world, I have learned over the years that it is easy to get this inaccurate error in terms of thread safety if you are not using a proven idiom. Therefore, I would like to make sure that I am using the correct idiom.

Can you show me an example of an Objective-C class that does this?

Here is my empty class I'm starting with ...

@interface TestClass : NSObject - (NSString *)doSomething:(NSUInteger)aParam; @end @implementation TestClass { } - (id)init { self = [super init]; if (self) { } return self; } - (NSString *)doSomething:(NSUInteger)aParam { // something with shared NSString loaded from text file, // depending on the value of aParam return @""; } @end 
+4
source share
4 answers

The idiomatic way to handle static properties in Objective-C hides them behind class methods (those with + ). Declare your string as static inside the implementation of your class method and use dispatch_once to initialize:

 + (id)stringFromFile { static dispatch_once_t once; static NSString *sharedString; dispatch_once(&once, ^{ sharedString = [NSString stringWithContentsOfFile:@"MyFile" encoding:... // ...supply proper parameters here... error:...]; }); return sharedString; } 

This way to configure static objects is thread safe. sharedString will be initialized once, even if the method is called from multiple threads simultaneously.

Now you can get your string from anywhere by calling [MyClass stringFromFile] .

+7
source

Create an instance variable for instances of the class to access and a static variable inside the designated initializer. Your designated initializer should create the string object once (by storing it in a static variable) and assign it to the instance variable each time. For instance:

 @implementation TestClass { NSString *_myString; } - (id)init { self = [super init]; if (self == nil) return nil; static dispatch_once_t once; static NSString *aString = nil; dispatch_once(&once, ^{ aString = ... // However you want to instantiate the string }); _myString = aString; return self; } 

This allows you to access the string in your instance methods as if it were a normal instance variable, even though the row is only created once and each instance points to one object.

+1
source
 - (NSString *)doSomething:(NSUInteger)aParam { static NSString *foo = nil; if (!foo) { //load foo } return @""; } 
0
source
0
source

All Articles