suchen

Heim  >  Fragen und Antworten  >  Hauptteil

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 Tage vor737

Antworte allen(6)Ich werde antworten

  • PHP中文网

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

    http://www.jianshu.com/p/08b1...
    看看这篇我的写博客.

    Antwort
    0
  • 黄舟

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

    又去stackovweflow找了下方法,我觉得既然是单例模式,调用者就应该严格按照单例的要求,通过统一的接口(这里是sharedInstance)去创建单例,而不应该出现调用[[class alloc] init]也能成功创建单例的情况,如果出现[[class alloc] init]的情况,我觉得更应该让Xcode给出警告不能用此方法

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

    Antwort
    0
  • PHPz

    PHPz2017-04-18 09:43:01

    额外创建有很多,还有new方法也可以,把这些方面都重载一遍返回 sharedManager 实例,或者直接抛出异常

    Antwort
    0
  • 迷茫

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

    覆盖allocWithZone和copyWithZone方法。
    因为通过alloc或者copy还是new,都是通过调用allocWithzone和copyWithzone来分配空间的。
    你可以把sharedManager 方法里面的代码写到这两个方法里面,就可以从根本实现了单例的情况

    Antwort
    0
  • 大家讲道理

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

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

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

    Antwort
    0
  • StornierenAntwort