在目标c中,java同步的等价物是什么? 我希望能够使我的单例方法安全,所以当它从2个不同的线程调用时,它们会尝试逐个使用它。
+(MyObject*) getSharedObject
{
if(!singleton)
{
singleton = [[MyObject alloc] init];
}
return singleton;
}
答案 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;
这样可以在实例化对象后避免不必要的锁定。