目标c中java同步的等价物是什么?我希望能够使我的单例方法安全,因此当从 2 个不同的线程调用它时,他们会尝试一个一个地使用它。
+(MyObject*) getSharedObject
{
if(!singleton)
{
singleton = [[MyObject alloc] init];
}
return singleton;
}
目标c中java同步的等价物是什么?我希望能够使我的单例方法安全,因此当从 2 个不同的线程调用它时,他们会尝试一个一个地使用它。
+(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
, using中初始化它dispatch_once
,这样做是正确的:
static MyObject *singleton = nil;
+ (void)initialize {
static dispatch_once_t pred;
dispatch_once(&pred, ^{ singleton = [[MyObject alloc] init]; } );
}
- (MyObject&)getSharedObject
{
return singleton;
}
为了同步单例创建,您应该使用单例的类作为要同步的对象。这是我通常的模式:
+(MyObject*) singleton
{
static MyObject* singleton = nil;
@synchronized([MyObject class])
{
if(singleton == nil)
{
singleton = [[MyObject alloc] init];
}
}
return singleton;
}
注意事项:
我已经把它变成了一个类方法。您实际上不必这样做,它将作为实例方法工作。
通常在引用类时在类方法中使用self
(或[self class]
在实例方法中)。但是,这在这里是错误的,因为子类将使用与 MyObject 类不同的对象进行同步。
I have put the return outside of the @synchronize
block. It is perfectly OK to return from inside the block, but if you do, you get a spurious clang static analyser warning saying the method might not return a value.
Edit
The above pattern is long since obsolete. It's best to use the dispatch_once
pattern
+(MyObject*) singleton
{
static dispatch_once_t onceToken;
static MyObject* singleton = nil;
dispatch_once (&onceToken, ^{
singleton = [[MyObject alloc] init];
});
return singleton;
}
我同意这两个答案。但是,如果想法是按需实例化,那么我会采用 Joshua 的建议,并使用双重检查锁定进行轻微修改:
if (!singleton)
@synchronized(something)
if (!singleton)
instantiate;
这样可以避免在对象实例化后不必要的锁定。