辛格尔顿在Interface Builder与ARC(Singleton in Interface

2019-08-03 01:34发布

我的问题是相当类似这样的: 使用辛格尔顿在界面生成器?

唯一的区别是,我使用ARC。 所以,如果简单,我的单身看起来像这样:

Manager.m

@implementation Manager

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

@end

所以,问题是,如果有可能将其用于Interface Builder中仍与ARC是?

当然,我明白,这可能是简单的只是重新改写了该类不ARC所以这个问题是相当的学术。 :)

Answer 1:

当笔尖未归档,它会尝试或者alloc / initalloc / initWithCoder:类的新实例。

所以,你可以做的是拦截该调用并重新路由到您的回单:

+ (id)sharedInstance {
  static Singleton *sharedInstance = nil;
  static dispatch_once_t onceToken;
  dispatch_once(&onceToken, ^{
    sharedInstance = [[self actualAlloc] actualInit];
  });
  return sharedInstance;
}

+ (id)actualAlloc {
  return [super alloc];
}

+ (id)alloc {
  return [Singleton sharedInstance];
}

- (id)actualInit {
  self = [super init];
  if (self) {
    // singleton setup...
  }
  return self;
}

- (id)init {
  return self;
}

- (id)initWithCoder:(NSCoder *)decoder {
  return self;
}

这使得-init-initWithCoder:安全地调用同一对象上多次。 它一般不建议允许这样做,但考虑到单身都已经是“一个地方的东西可以得到真正靠不住”的情况下,这是不是你可以做最坏的打算。



Answer 2:

只要是完整的,这里有可能从Interface Builder中使用辛格尔顿的实现。 所不同的是在actualAlloc方法。 作为[super alloc]仍叫[self allocWithZone:] -这将不分配的对象。

Singleton.h

@interface Singleton : NSObject

+ (instancetype)sharedInstance;

@end

Singleton.m

@implementation Singleton

+ (instancetype)sharedInstance {
    __strong static id _sharedInstance = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _sharedInstance = [[self _alloc] _init];
    });
    return _sharedInstance;
}

+ (id)allocWithZone:(NSZone *)zone {
    return [self sharedInstance];
}

+ (id)alloc {
    return [self sharedInstance];
}

- (id)init {
    return self;
}

+ (id)_alloc {
    return [super allocWithZone:NULL]; //this is important, because otherwise the object wouldn't be allocated
}

- (id)_init {
    return [super init];
}

@end


Answer 3:

@Eugene,从iOS的文档集,“由于历史的原因, alloc调用allocWithZone: ”,那么,就没有必要重新实现alloc方法。



文章来源: Singleton in Interface Builder with ARC