Objective-C: static field and singleton pattern implementation

Good afternoon friends.

Once again a stupid question about Obj-C from a beginner :)

I am trying to implement a singleton design pattern in Obj-C:

@interface SampleSingleton : NSObject { @private static SampleSingleton* instance; } +(SampleSingleton*) getInstance; 

The compiler returns an error: "expected qualifier-classifier-list to" static ".

+1
source share
5 answers

The following is a snippet of Objective-C code that I use to correctly implement a single-user single-threaded implementation

header file:

 /* * * Singleton interface that match Cocoa recommendation * @ http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/CocoaFundamentals/CocoaObjects/CocoaObjects.html#//apple_ref/doc/uid/TP40002974-CH4-SW32 * extended with thread-safe pattern */ @interface MyCustomManager : NSObject { } #pragma mark Singleton Thred-Safe Pattern + (MyCustomManager *) sharedInstance; + (id)allocWithZone:(NSZone *)zone; - (id)copyWithZone:(NSZone *)zone; - (id)retain; - (NSUInteger)retainCount; - (void)release; - (id)autorelease; #pragma mark - 

implementation file:

 /* * My custom manager Class singleton implementation */ @implementation MyCustomManager #pragma mark Initializers /* * specific initialize goes here */ - (void) specificInitialize { // ... } /* * Ensure any owned object is properly released */ - (void) dealloc { [super dealloc]; } #pragma mark - #pragma mark Singleton Thred-Safe Pattern //- use Volatile to make sure we are not foiled by CPU caches static void * volatile sharedInstance = nil; /* * retrieve sharedInstance based on OSAtomicCompareAndSwapPtrBarrier that * acts as both a write barrier for the setting thread and a read barrier from the testing thread * more info @ http://stackoverflow.com/questions/145154/what-does-your-objective-c-singleton-look-like/2449664#2449664 * and http://stackoverflow.com/questions/6915/thread-safe-lazy-contruction-of-a-singleton-in-c/6943#6943 */ + (MyCustomManager *) sharedInstance { //- check sharedInstance existenz while (!sharedInstance) { //- create a temporary instance of the singleton id temp = [super allocWithZone:NSDefaultMallocZone()]; //- The OSAtomicCompareAndSwapPtrBarrier function provided on Mac OS X //- checks whether sharedInstance is NULL and only actually sets it to temp to it if it is. //- This uses hardware support to really, literally only perform the swap once and tell whether it happened. if(OSAtomicCompareAndSwapPtrBarrier(0x0, (void *)temp, &sharedInstance)) { //- compute singleton initialize MyCustomManager *singleton = (MyCustomManager *) sharedInstance; [singleton specificInitialize]; } else { //- if the swap didn't take place, delete the temporary instance [temp release]; temp = nil; } } //- return computed sharedInstance return sharedInstance; } /* * method to ensure that another instance is not allocated if someone tries to allocate * and initialize an instance of your class directly instead of using the class factory method. * Instead, it just returns the shared object. */ + (id)allocWithZone:(NSZone *)zone { return [[self sharedInstance] retain]; } /* * Implements the base protocol methods to do the appropriate things to ensure singleton status. * Applies to memory-managed code, not to garbage-collected code */ - (id)copyWithZone:(NSZone *)zone { return self; } /* * Implements the base protocol methods to do the appropriate things to ensure singleton status. * Applies to memory-managed code, not to garbage-collected code */ - (id)retain { return self; } /* * Implements the base protocol methods to do the appropriate things to ensure singleton status. * Applies to memory-managed code, not to garbage-collected code */ - (NSUInteger)retainCount { return NSUIntegerMax; //denotes an object that cannot be released } /* * Implements the base protocol methods to do the appropriate things to ensure singleton status. * Applies to memory-managed code, not to garbage-collected code */ - (void)release { //do nothing } /* * Implements the base protocol methods to do the appropriate things to ensure singleton status. * Applies to memory-managed code, not to garbage-collected code */ - (id)autorelease { return self; } #pragma mark - 

To help you get started with Objective-C and not get lost in the project structure, you might think that the structure of the project matches your file system, since your project will become larger, you won’t get lost.

Also consider using the correct class naming convention and stick to it.

I provide you my sample:

  • Any class that matches the singleton pattern is called using the dispatcher suffix (for example, MyCustomManager).

  • Any static class is called using an auxiliary suffix (for example, MyCustomHelper).

  • Any class designed to control a specific process is called using the controller suffix (for example, MyParticularTaskConstroller).

  • Any UI control that inherits from another control must have a control suffix (for example, MyCustomDetailCell inheriting from UITableViewCell)

Hope this helps.

+8
source

You cannot use static in a class interface declaration. Singleton must be declared as a static standalone variable in the .m file. I usually do this (if I feel like I can’t escape the single):

 @interface SampleSingleton : NSObject { @private } +(SampleSingleton*) theSingleton; @end // .m file @implementation SampleSingleton +(SampleSingleton*) theSingleton { static SampleSingleton* theSingleton = nil; if (theSingleton == nil) { theSingleton = [[SampleSingleton alloc] init]; } return theSingleton; } 
+8
source

Please check out my question here and Nick DeMoore's wonderful answer (with lots of comments and code fixes). Having a singleton that you can plug into IB (well, whatever you call it in Xcode 4) is really useful.

The nice thing is that you can use the same Singleton and connect some of its outputs in one NIB, and some of its outputs in another ... since this is really a singleton, there can only be one instance in the entire runtime system. It works great.

Note. . Every time you use Singleton, people say this is a bad idea.

+1
source

Static string SampleSingleton* instance; cannot be in the @interface section. Most people have expressed it above.

Objective-c really does not lend itself to a syntax pattern, as well as to some other languages. However, there are several different implementations that you can see in this question .

Some people argue that Singleton is not a very good example, and I'm trying to wean myself from using it, but it's my choice.

0
source

This is how I usually use the singleton method

 +(SampleSingleton * )sampleSingleton { static SampleSingleton * theSampleSingleton = nil; if( theSampleSingleton == nil ) theSampleSingleton = [[SampleSingleton alloc] init]; return theSampleSingleton; } 

to make this thread safe you would do

 +(SampleSingleton * )sampleSingleton { static SampleSingleton * theSampleSingleton = nil; if( theSampleSingleton == nil ) { @syncronise([SampleSingleton class]) { if( theSampleSingleton == nil ) theSampleSingleton = [[SampleSingleton alloc] init]; } } return theSampleSingleton; } 

In addition, instead of using singleton, you already have a singleton in the form of UIApplicationDelegate, you can always add a delegation method to get your SampleSingleton from your delegate.

Another point to consider about singletones is that you really need to enforce singletones, UIApplication has a sharedApplication that has the function of creating a singleton, but there is nothing really stopping you from creating a new instance.

0
source

All Articles