Create singleton using GCD's dispatch_once in Objective-C

后端 未结 10 2352
爱一瞬间的悲伤
爱一瞬间的悲伤 2020-11-22 07:26

If you can target iOS 4.0 or above

Using GCD, is it the best way to create singleton in Objective-C (thread safe)?

+ (instancetype)sharedInstance
{
          


        
相关标签:
10条回答
  • 2020-11-22 07:46

    This is a perfectly acceptable and thread-safe way to create an instance of your class. It may not technically be a "singleton" (in that there can only ever be 1 of these objects), but as long as you only use the [Foo sharedFoo] method to access the object, this is good enough.

    0 讨论(0)
  • 2020-11-22 07:47

    Dave is correct, that is perfectly fine. You may want to check out Apple's docs on creating a singleton for tips on implementing some of the other methods to ensure that only one can ever be created if classes choose NOT to use the sharedFoo method.

    0 讨论(0)
  • 2020-11-22 07:48

    MySingleton.h

    @interface MySingleton : NSObject
    
    +(instancetype)sharedInstance;
    
    +(instancetype)alloc __attribute__((unavailable("alloc not available, call sharedInstance instead")));
    -(instancetype)init __attribute__((unavailable("init not available, call sharedInstance instead")));
    +(instancetype)new __attribute__((unavailable("new not available, call sharedInstance instead")));
    -(instancetype)copy __attribute__((unavailable("copy not available, call sharedInstance instead")));
    
    @end
    

    MySingleton.m

    @implementation MySingleton
    
    +(instancetype)sharedInstance {
        static dispatch_once_t pred;
        static id shared = nil;
        dispatch_once(&pred, ^{
            shared = [[super alloc] initUniqueInstance];
        });
        return shared;
    }
    
    -(instancetype)initUniqueInstance {
        return [super init];
    }
    
    @end
    
    0 讨论(0)
  • 2020-11-22 07:51
    @interface className : NSObject{
    +(className*)SingleTonShare;
    }
    
    @implementation className
    
    +(className*)SingleTonShare{
    
    static className* sharedObj = nil;
    static dispatch_once_t once = 0;
    dispatch_once(&once, ^{
    
    if (sharedObj == nil){
        sharedObj = [[className alloc] init];
    }
      });
         return sharedObj;
    }
    
    0 讨论(0)
  • 2020-11-22 07:55

    You can avoid that the class be allocated with overwriting the alloc method.

    @implementation MyClass
    
    static BOOL useinside = NO;
    static id _sharedObject = nil;
    
    
    +(id) alloc {
        if (!useinside) {
            @throw [NSException exceptionWithName:@"Singleton Vialotaion" reason:@"You are violating the singleton class usage. Please call +sharedInstance method" userInfo:nil];
        }
        else {
            return [super alloc];
        }
    }
    
    +(id)sharedInstance
    {
        static dispatch_once_t p = 0;
        dispatch_once(&p, ^{
            useinside = YES;
            _sharedObject = [[MyClass alloc] init];
            useinside = NO;
        });   
        // returns the same object each time
        return _sharedObject;
    }
    
    0 讨论(0)
  • 2020-11-22 07:58

    To create thread safe singleton you can do like this:

    @interface SomeManager : NSObject
    + (id)sharedManager;
    @end
    
    /* thread safe */
    @implementation SomeManager
    
    static id sharedManager = nil;
    
    + (void)initialize {
        if (self == [SomeManager class]) {
            sharedManager = [[self alloc] init];
        }
    }
    
    + (id)sharedManager {
        return sharedManager;
    }
    @end
    

    and this blog explain singleton very well singletons in objc/cocoa

    0 讨论(0)
提交回复
热议问题