我怎样才能多线程创建延迟加载 属性?
How can I multithread the creation of a lazily loaded property?
- (NSHashTable *)pollers
{
if (!_pollers) {
dispatch_sync(self.serialQueue, ^{
_pollers = [NSHashTable weakObjectsHashTable];
});
}
return _pollers;
}
pollers 是单例上的非原子 属性。在将对象添加到轮询器的单例中还有一些其他方法,我使用@synchronized 来添加它们 ([self.pollers addObject:____])。
无论如何...我对上面的代码有疑问。如果 2 个线程同时调用此函数,它们都可以通过 if (!_pollers)
代码,然后它们都将在我们的自定义 serialQueue 上同步调度 _pollers = [NSHashTable weakObjectsHashTable];
代码。所以我们实际上 运行 代码两次。
有更好的方法吗?
像这样使用dispatch_once
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
dispatch_sync(self.serialQueue, ^{
_pollers = [NSHashTable weakObjectsHashTable];
});
});
return pollers;
为此你只需要一个dispatch_once
函数
您的串行队列现在是多余的,因为 dispatch_once
将确保该块仅被调用一次(即使从多个线程同时调用),.
The documentation clearly states that:
If [dispatch_once is] called simultaneously from multiple threads, this function waits synchronously until the block has completed.
你的if
说法也是多余的,。
因此你只需要:
- (NSHashTable *)pollers
{
static dispatch_once_t t;
dispatch_once(&t, ^{
_pollers = [NSHashTable weakObjectsHashTable];
});
return _pollers;
}
同样值得注意的是,您需要一个线程安全的单例 sharedInstance
实现,以便它是防弹的。您可以使用 dispatch_once
以几乎相同的方式执行此操作。例如:
static singleton* sharedInstance;
+(instancetype) sharedInstance {
static dispatch_once_t t;
dispatch_once(&t, ^{
sharedInstance = [[self alloc] init];
});
return sharedInstance;
}
- (NSHashTable *)pollers
{
if (!_pollers) {
dispatch_sync(self.serialQueue, ^{
_pollers = [NSHashTable weakObjectsHashTable];
});
}
return _pollers;
}
pollers 是单例上的非原子 属性。在将对象添加到轮询器的单例中还有一些其他方法,我使用@synchronized 来添加它们 ([self.pollers addObject:____])。
无论如何...我对上面的代码有疑问。如果 2 个线程同时调用此函数,它们都可以通过 if (!_pollers)
代码,然后它们都将在我们的自定义 serialQueue 上同步调度 _pollers = [NSHashTable weakObjectsHashTable];
代码。所以我们实际上 运行 代码两次。
有更好的方法吗?
像这样使用dispatch_once
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
dispatch_sync(self.serialQueue, ^{
_pollers = [NSHashTable weakObjectsHashTable];
});
});
return pollers;
为此你只需要一个dispatch_once
函数
您的串行队列现在是多余的,因为 dispatch_once
将确保该块仅被调用一次(即使从多个线程同时调用),
The documentation clearly states that:
If [dispatch_once is] called simultaneously from multiple threads, this function waits synchronously until the block has completed.
你的if
说法也是多余的,
因此你只需要:
- (NSHashTable *)pollers
{
static dispatch_once_t t;
dispatch_once(&t, ^{
_pollers = [NSHashTable weakObjectsHashTable];
});
return _pollers;
}
同样值得注意的是,您需要一个线程安全的单例 sharedInstance
实现,以便它是防弹的。您可以使用 dispatch_once
以几乎相同的方式执行此操作。例如:
static singleton* sharedInstance;
+(instancetype) sharedInstance {
static dispatch_once_t t;
dispatch_once(&t, ^{
sharedInstance = [[self alloc] init];
});
return sharedInstance;
}