什么相当于Objective-C中的同步?

时间:2010-11-02 02:03:16

标签: java objective-c singleton synchronized

在目标c中,java同步的等价物是什么? 我希望能够使我的单例方法安全,所以当它从2个不同的线程调用时,它们会尝试逐个使用它。

+(MyObject*) getSharedObject
{
     if(!singleton)
     {
          singleton = [[MyObject alloc] init];
     }
     return singleton;
}

4 个答案:

答案 0 :(得分:10)

Obj-C有一个同步的构造

-(MyObject*) getSharedObject
{
@synchronized(something)
{
     if(!singleton)
     {
          singleton = [[MyObject alloc] init];
     }
     return singleton;
}
}

从同步块中返回“正确”的事情

答案 1 :(得分:9)

Joshua的回答是正确的,但要求你有一个要同步的对象。如果你不小心,对单身人士这样做会导致各种奇怪的竞争条件。单例的标准模式是使用dispatch_once+initialize中对其进行初始化,这样做是正确的:

static MyObject *singleton = nil;

+ (void)initialize {
  static dispatch_once_t pred;
  dispatch_once(&pred, ^{ singleton = [[MyObject alloc] init]; } );
}

- (MyObject&)getSharedObject
{
  return singleton;
}

答案 2 :(得分:8)

为了同步单例创建,您应该使用单例类作为要同步的对象。这是我通常的模式:

+(MyObject*) singleton
{
    static MyObject* singleton = nil;
    @synchronized([MyObject class])
    {
         if(singleton == nil)
         {
             singleton = [[MyObject alloc] init];
         }
    }
    return singleton;
}

注意事项:

  • 我已经把它变成了一个类方法。你实际上并不需要,它将作为一个实例方法。

  • 通常在引用类的类方法中,您可以在实例方法中使用self(或[self class])。但是,这在这里是错误的,因为子类将使用不同的对象与MyObject类同步。

  • 我已将回程放在@synchronize区块之外。从块内部返回是完全可以的,但是如果你这样做,你会得到一个虚假的clang静态分析器警告说该方法可能没有返回值。


修改

上述模式早已过时。最好使用dispatch_once模式

+(MyObject*) singleton
{
    static dispatch_once_t onceToken;
    static MyObject* singleton = nil;

    dispatch_once (&onceToken, ^{
        singleton = [[MyObject alloc] init];
    });
    return singleton;
}

答案 3 :(得分:-1)

我同意这两个答案。但是,如果想要按需实例化,那么我会使用双重检查锁定稍微修改约书亚的建议:

if (!singleton)  
   @synchronized(something)  
      if (!singleton)  
         instantiate;

这样可以在实例化对象后避免不必要的锁定。