Java 在Objective-C中同步的等价物是什么?

Java 在Objective-C中同步的等价物是什么?,java,objective-c,singleton,synchronized,Java,Objective C,Singleton,Synchronized,在objective c中,java同步的等价物是什么? 我希望能够使我的单例方法安全,所以当从两个不同的线程调用它时,它们会尝试逐个使用它 +(MyObject*) getSharedObject { if(!singleton) { singleton = [[MyObject alloc] init]; } return singleton; } Obj-C具有同步构造 -(MyObject*) getSharedObject

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

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

Obj-C具有同步构造

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

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

Joshua的回答是正确的,但需要有一个要同步的对象。如果你不小心的话,为单身汉这样做可能会导致各种奇怪的种族状况。单例的标准模式是在
+initialize
中使用进行初始化,这样做是正确的:

static MyObject *singleton = nil;

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

- (MyObject&)getSharedObject
{
  return singleton;
}

我同意两个答案。但是如果想法是按需实例化,那么我会同意Joshua的建议,使用双重检查锁定进行轻微修改:

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

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

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

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

  • 我把它变成了一个类方法。实际上,您不必这样做,它将作为一个实例方法工作

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

  • 我已将返回置于
    @synchronize
    块之外。从块内部返回是完全可以的,但是如果您这样做,您会得到一个虚假的叮当声静态分析器警告,说该方法可能不会返回值


编辑

上述模式早已过时。最好使用
dispatch\u once
模式

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

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

重复不完全是重复,一个相关的问题是肯定的。在singleton类上同步,然后没有奇怪的竞争条件。这是苹果公司推荐的风格。双重检查锁定涉及许多微妙的可能竞争条件。我会避免的。我感谢你的反馈JeremyP,我承认我没有意识到这些问题。然而,我仍然认为理解这些问题并正确处理这些问题是值得的,特别是如果这段代码的流量很大,那么在知情的情况下添加一个可能的争论点就太糟糕了。非常感谢!不用担心选票。我们在这里互相学习。静态MyObject*singleton=nil;这不是将singleton对象设置为nil,并在每次调用该方法时重新实例化吗?IIRC,在ObjC中,static基本上意味着“只有一个存在”,因此,它只初始化一次。Obj-C中的static与C中的static相同,这意味着只有在您还可以说
MyObject.class
而不是
[MyObject class]
@cubblehman时,行才会初始化。我不确定点表示法是否适用于类属性。无论如何,我一直不喜欢Objective-C中的点表示法。只是一个小的修正,我认为OP想要使用静态方法