iOS中的Singleton对象

时间:2015-08-21 14:22:29

标签: ios objective-c cocoa singleton

我们知道单个对象只能实例化一次,我们在目标C中使用单例来全局访问共享资源。我们也知道使用以下方法实例化单身。

undefined += 1 !== 1

但我也可以这样做 -

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

现在这样我也可以创建同一个单例类的另一个实例,如果它有两个实例,那么该类如何是单例。

请澄清。

4 个答案:

答案 0 :(得分:2)

你可以禁止init使用这样的技巧调用: 将- (instancetype)init NS_UNAVAILABLE;定义添加到您的单例界面。

而不是[[PhotoManager alloc] init];使用[[[self class] 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];会导致编译错误。

答案 1 :(得分:0)

只有在使用sharedManager:类方法时,对象才具有单例行为。您实例化对象的所有其他方式都不能保证生成单个对象。

答案 2 :(得分:0)

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

答案 3 :(得分:-1)

写作时

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