您好,我有一个针对单例的 iOS 以前版本的实现,如下所示:
.h文件
@interface CartSingleton : NSObject
{
}
+(CartSingleton *) getSingleton;
.m文件
@implementation CartSingleton
static CartSingleton *sharedSingleton = nil;
+(CartSingleton *) getSingleton
{
if (sharedSingleton !=nil)
{
NSLog(@"Cart has already been created.....");
return sharedSingleton;
}
@synchronized(self)
{
if (sharedSingleton == nil)
{
sharedSingleton = [[self alloc]init];
NSLog(@"Created a new Cart");
}
}
return sharedSingleton;
}
//==============================================================================
+(id)alloc
{
@synchronized([CartSingleton class])
{
NSLog(@"inside alloc");
NSAssert(sharedSingleton == nil, @"Attempted to allocate a second instance of a singleton.");
sharedSingleton = [super alloc];
return sharedSingleton;
}
return nil;
}
//==============================================================================
-(id)init
{
self = [super init];
}
但是在网络上我看到人们已经使用以下代码实现了单例设计模式:
+ (id)sharedInstance
{
static dispatch_once_t pred = 0;
__strong static id _sharedObject = nil;
dispatch_once(&pred, ^{
_sharedObject = [[self alloc] init]; // or some other init method
});
return _sharedObject;
}
请有经验的前辈指点一下。 我是新手,对 Singleton 的旧 iOS 实现和新的 iOS 实现感到非常困惑,哪个是正确的?
非常感谢
最佳答案
严格来说,您必须使用:
+ (MySingleton*) instance {
static dispatch_once_t _singletonPredicate;
static MySingleton *_singleton = nil;
dispatch_once(&_singletonPredicate, ^{
_singleton = [[super allocWithZone:nil] init];
});
return _singleton;
}
+ (id) allocWithZone:(NSZone *)zone {
return [self instance];
}
现在您保证不能调用 alloc/init 并创建另一个实例。
说明:实例方法在类级别,是您获取单例引用的主要访问方法。该方法仅使用 dispatch_once() 内置队列,该队列只会执行一次 block 。运行时如何保证 block 只执行一次?使用您提供的谓词(dispatch_once_t 类型)。这个低级调用将保证即使有多个线程尝试调用它,也只有一个成功,其他的等待直到第一个完成然后返回。
我们覆盖 allocWithZone 的原因是因为 alloc 调用 allocWithZone 传递 nil 作为区域(对于默认区域)。为了防止流氓代码分配和初始化另一个实例,我们覆盖了 allocWithZone 以便传回的实例是已经初始化的单例。这可以防止创建第二个实例。
关于objective-c - iOS 5 中的单例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8796529/