我的问题与此问题非常相似:Use Singleton In Interface Builder?
唯一的区别是我使用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
所以问题是,是否可以将它用于仍然使用ARC的Interface Builder?
当然,我理解在不使用ARC的情况下重写该类可能更简单,因此问题相当于学术性。 :)
答案 0 :(得分:10)
取消存档笔尖后,它会尝试alloc
/ init
或alloc
/ 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:
。一般不建议允许这样做,但鉴于单身人士已经成为“事情变得非常糟糕的地方”,这不是你能做的最糟糕的事情。
答案 1 :(得分:3)
为了完成,这里是Singleton的一个实现,可以在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
答案 2 :(得分:0)
alloc
调用allocWithZone:
。”,因此,无需重新实现alloc
方法。