objective-c - iOS 5 中的单例?

标签 objective-c ios5 singleton

您好,我有一个针对单例的 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/

相关文章:

Objective-C 内省(introspection)/反射(reflection)

java - 存储过程与单例 Java

java - 拥有 'setter'/实例变量会导致单例 DAO 出现竞争条件吗?

java - 如何防止 progurad 保留单例类名称

ios - 在 Objective c 中处理多线程

iphone - iPhone 上的 "untrusted server certificate"

objective-c - 在 iOS 中从文本文件创建对象的最有效方法

ios - 序列化我的自定义 nsobject 以通过 http 发送

iphone - 从 NSMutableArray 中删除空值

ios - Core Image CIColorControls 亮度滤镜会产生错误的效果。如何更改图像的亮度?