search

Home  >  Q&A  >  body text

objective-c - 如何避免通过[[alloc] init]创建iOS单例类

网站普遍的创建单例类的方法有下面两种:

+ (instancetype)sharedManager {
    static id _sharedInstance = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _sharedInstance = [[self alloc] init];
    });
    return _sharedInstance;
}
+ (instancetype)sharedManager {
    static id _sharedInstance = nil;
    @synchronized(self) {
        if (_sharedInstance == nil)
            _sharedInstance = [[self alloc] init];
    }
    return _sharedInstance;
}

但是该如何避免意外的用[[alloc] init]创建呢?主要是发现网上找到的大多仅仅只有上面的代码,少有考虑被init或者copy的情况

大家讲道理大家讲道理2771 days ago741

reply all(6)I'll reply

  • PHP中文网

    PHP中文网2017-04-18 09:43:01

    http://www.jianshu.com/p/08b1...
    Check out this blog post of mine.

    reply
    0
  • 黄舟

    黄舟2017-04-18 09:43:01

    I went to stackovweflow again to find a method. I think since it is a singleton mode, the caller should strictly follow the requirements of the singleton and create a singleton through a unified interface (here sharedInstance), and should not call [[class alloc] init] can also successfully create a singleton. If [[class alloc] init] occurs, I think Xcode should give a warning not to use this method

    - (instancetype)init NS_UNAVAILABLE;
    + (instancetype)new NS_UNAVAILABLE;

    reply
    0
  • PHPz

    PHPz2017-04-18 09:43:01

    There are many additional creations, and there is also the new method. Overload these aspects to return a sharedManager instance, or throw an exception directly

    reply
    0
  • 迷茫

    迷茫2017-04-18 09:43:01

    Override allocWithZone and copyWithZone methods.
    Because whether through alloc, copy or new, space is allocated by calling allocWithzone and copyWithzone.
    You can write the code in the sharedManager method into these two methods, and you can realize the singleton situation from the ground up

    reply
    0
  • 大家讲道理

    大家讲道理2017-04-18 09:43:01

    • (instancetype)init {
      @throw [NSException exceptionWithName:@"Disable" reason:@"Please use init instead..." userInfo:nil];
      return self;
      }

    reply
    0
  • 天蓬老师

    天蓬老师2017-04-18 09:43:01

    Just write it like this

    static Singleton *slt = nil;
    
    + (instancetype)sharedInstance{
       static dispatch_once_t onceToken;
       dispatch_once(&onceToken, ^{
           slt = [[self alloc]init];
       });
       return slt;
    }
    
    + (instancetype)allocWithZone:(struct _NSZone *)zone
    {
       static dispatch_once_t onceToken;
       dispatch_once(&onceToken, ^{
           slt = [super allocWithZone:zone];
          
       });
       return slt;
    }
    
    - (id)copyWithZone:(NSZone *)zone
    {
       return slt;
    }

    reply
    0
  • Cancelreply