搜尋

首頁  >  問答  >  主體

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的情况

大家讲道理大家讲道理2899 天前778

全部回覆(6)我來回復

  • PHP中文网

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

    http://www.jianshu.com/p/08b1...
    看看這篇我的寫部落格.

    回覆
    0
  • 黄舟

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

    又去stackovweflow找了下方法,我覺得既然是單例模式,呼叫者就應該嚴格按照單例的要求,透過統一的介面(這裡是sharedInstance)去創建單例,而不應該出現呼叫[[class alloc] init]也能成功創建單例的情況,如果出現[[class alloc] init]的情況,我覺得更應該讓Xcode給出警告不能用此方法

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

    回覆
    0
  • PHPz

    PHPz2017-04-18 09:43:01

    額外創建有很多,還有new方法也可以,把這些方面都重載一遍回傳 sharedManager 實例,或者直接拋出異常

    回覆
    0
  • 迷茫

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

    覆蓋allocWithZone和copyWithZone方法。
    因為透過alloc或copy還是new,都是透過呼叫allocWithzone和copyWithzone來分配空間的。
    你可以把sharedManager 方法裡面的程式碼寫到這兩個方法裡面,就可以從根本實作了單例的情況

    回覆
    0
  • 大家讲道理

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

    • (instancetype)init {
      @throw [NSException異常WithName:@"停用"原因:@"請使用init代替..." userInfo:nil];
      return self;
      }

    🎜🎜

    回覆
    0
  • 天蓬老师

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

    這樣寫就可以了

    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;
    }

    回覆
    0
  • 取消回覆