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

ary*_*axt 5 java singleton objective-c synchronized

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

+(MyObject*) getSharedObject
{
     if(!singleton)
     {
          singleton = [[MyObject alloc] init];
     }
     return singleton;
}
Run Code Online (Sandbox Code Playgroud)

Jos*_*erg 10

Obj-C具有同步构造

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

从同步块内返回做"正确"的事情


Bar*_*ark 9

约书亚的答案是正确的,但要求你有一个同步的对象.如果你不小心的话,对一个单身人士这样做会导致各种奇怪的竞争条件.对于单身的标准模式是在初始化+initialize,使用dispatch_once,它做正确的事:

static MyObject *singleton = nil;

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

- (MyObject&)getSharedObject
{
  return singleton;
}
Run Code Online (Sandbox Code Playgroud)

  • 在单身人士的班级上同步,然后没有奇怪的竞争条件. (2认同)

Jer*_*myP 8

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

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

注意事项:

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

  • 通常在类方法中引用类时,您将使用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;
}
Run Code Online (Sandbox Code Playgroud)

  • Obj-C中的静态与C中的静态相同,这意味着该行只会被初始化一次 (3认同)
  • static MyObject*singleton = nil; 这不是将singleton对象设置为nil,并在每次调用方法时重新实例化它吗? (2认同)