iOS中的单例对象[重复]
Posted
技术标签:
【中文标题】iOS中的单例对象[重复]【英文标题】:Singleton Object in iOS [duplicate] 【发布时间】:2015-08-21 14:22:29 【问题描述】:我们知道单例对象只能实例化一次,我们在目标 C 中使用单例来全局访问共享资源。我们也知道单例是使用以下方法实例化的。
+ (instancetype)sharedManager
static PhotoManager *sharedPhotoManager = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^
sharedPhotoManager = [[[self class] alloc] init];
sharedPhotoManager->_photosArray = [NSMutableArray array];
);
return sharedPhotoManager;
但我也可以这样做 -
PhotoManager *sharedManager = [[PhotoManager alloc] init];
现在这样我也可以创建同一个单例类的另一个实例,那么如果它有两个实例,这个类怎么会是单例的。
请澄清。
【问题讨论】:
【参考方案1】:您可以使用以下技巧禁止init
的呼叫:
将- (instancetype)init NS_UNAVAILABLE;
定义添加到您的单例界面。
用[[[self class] alloc] init];
代替[[PhotoManager alloc] init];
PhotoManager *sharedManager = [[PhotoManager alloc] init];
不会编译。
这是我的例子:
@interface SomeSingleton : NSObject
+ (instancetype)sharedInstance;
- (instancetype)init NS_UNAVAILABLE;
@end
@implementation SomeSingleton
+ (instancetype)sharedInstance
static dispatch_once_t onceToken;
static SomeSingleton *instance;
dispatch_once(&onceToken, ^
instance = [[[self class] alloc] init];
);
return instance;
- (instancetype)init
self = [super init];
return self;
@end
结果SomeSingleton *s1 = [SomeSingleton sharedInstance];
有效,但SomeSingleton *s2 = [[SomeSingleton alloc] init];
导致编译错误。
【讨论】:
我认为在类方法中你甚至可以省略对class
的调用,因为在类方法中,self
已经引用了类。
@LukasSpieß,你是对的【参考方案2】:
仅当您使用sharedManager:
类方法时,您才具有对象的单例行为。实例化对象的所有其他方式都不能保证生成单例对象。
【讨论】:
【参考方案3】:Objective-C 允许你做很多你不打算做的事情。如果您知道方法名称,就像调用私有方法一样。
如果你痴迷于确保你的类只用作单例,也许这样的东西会有用:
static PhotoManager *sharedPhotoManager = nil;
+ (instancetype)sharedManager
if (!sharedPhotoManager)
sharedPhotoManager = [[PhotoManager alloc] init];
return sharedPhotoManager;
- (instancetype)init
if (sharedPhotoManager)
// init method is allowed to return different object
return sharedPhotoManager;
self = [super init];
if (self)
return self;
【讨论】:
【参考方案4】:当你写作时
PhotoManager *sharedManager = [[PhotoManager alloc] init];
你没有得到你的 sharedInstance,你正在创建一个新的。你应该使用它的方式是
[PhotoManager sharedInstance];
而不是
PhotoManager *sharedManager = [[PhotoManager alloc] init];
当您创建一个从未使用过 alloc init 的单例类时,您应该始终使用 sharedInstance 方法在您的应用中保持相同的实例
顺便说一句...正如T_77 建议的那样,您应该使用 dispatch_once 而不是您的实现来创建实例。
+ (instancetype)sharedInstance
static dispatch_once_t once;
static id sharedInstance;
dispatch_once(&once, ^
sharedInstance = [[self alloc] init];
);
return sharedInstance;
【讨论】:
我还是投了反对票:P @T_77,可能是因为你没有回答这个问题,如果确实可以创建多个对象,为什么它被称为单例。 你是对的。我会记住的。 :) @SonGoku68 请仔细阅读问题。我知道获取共享实例的方法。但我的问题是,如果我们可以分配 init,如何防止创建同一个类的另一个实例。以上是关于iOS中的单例对象[重复]的主要内容,如果未能解决你的问题,请参考以下文章