iOS 5中的Singleton?

ban*_*ing 11 singleton objective-c ios5

嗨我有一个实现以前版本的iOS的单身如下:

.h文件

@interface CartSingleton : NSObject 
{

}
+(CartSingleton *) getSingleton;
Run Code Online (Sandbox Code Playgroud)

.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];
}
Run Code Online (Sandbox Code Playgroud)

但是在网络上,我看到人们使用以下代码实现了Singleton设计模式:

+ (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;
}
Run Code Online (Sandbox Code Playgroud)

请有经验的人指导我.我是新手,并且在Singleton的旧iOS实现和新的实现之间彻底混淆了哪个是正确的?

非常感谢

Καr*_*hικ 19

严格来说,你必须使用:

+ (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];
 }
Run Code Online (Sandbox Code Playgroud)

现在你保证不能调用alloc/init并创建另一个实例.

Explanation:实例方法位于类级别,是获取对单例的引用的主要访问方法.该方法只使用dispatch_once()内置队列,该队列只执行一次块.运行时如何保证块只执行一次?使用您提供的谓词(类型为dispatch_once_t).这个低级调用将保证即使有多个线程试图调用它,只有一个成功,其他线程等到第一个完成然后返回.

我们覆盖allocWithZone的原因是因为alloc调用allocWithZone传递nil作为区域(对于默认区域).为了防止恶意代码分配和初始化另一个实例,我们覆盖allocWithZone,以便传回的实例是已经初始化的单例.这可以防止创建第二个实例.


And*_*jov 9

dispatch_once片段在功能上与其他片段相同.您可以在http://developer.apple.com/library/mac/#documentation/Darwin/Reference/Manpages/man3/dispatch_once.3.html上阅读相关内容.

这就是我用于单身人士的方式:

+ (MySingleton*) getOne {
    static MySingleton* _one = nil;

    @synchronized( self ) {
        if( _one == nil ) {
            _one = [[ MySingleton alloc ] init ];
        }
    }

    return _one;
}
Run Code Online (Sandbox Code Playgroud)

注意:在大多数情况下,您甚至不需要使用@synchronized(但这样安全).