有时我想在对象的生命周期中执行一次代码。过去我设置了一个BOOL
可以检查的属性,但这有点尴尬。Objective-C 中是否有一些内置的东西可以优雅地完成这个任务?有点像dispatch_once
,但与对象相关,而不是应用程序的生命周期。
问问题
223 次
2 回答
2
根据苹果文档 dispatch_once
,在这种情况下不应该使用!
谓词必须指向存储在全局或静态范围内的变量。使用带有自动或动态存储的谓词的结果是未定义的。
另一种方法是使用原子操作。这样,还可以确保代码在对象的生命周期内只执行一次。
@implementation MyClass {
// int32_t initialized;
BOOL initialized;
}
- (void)myMethod {
dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// if (OSAtomicTestAndSetBarrier(1, &initialized) == NO) {
if (!initialized) {
// do stuff once
initialized = YES;
}
});
};
@end
编辑:initialized
一直是 BOOL 类型,由于 Chris Devereux 和 Stephen Canon 的评论,该类型已得到纠正。
编辑:正如 Catfish_Man 指出的那样,使用原子操作可能会导致问题。因此,您必须使用 dispatch_sync 或类似的东西来包装整个东西,这使得使用原子操作变得毫无意义。
于 2013-07-23T10:45:53.637 回答
1
您可以使用 dispatch_once_t 实例变量来执行此操作。如果您要在多个线程上使用此对象,请注意微妙的线程问题(并非特定于 dispatch_once)。您需要在 init 结束时设置内存屏障,以确保 ivar 的初始化在对象对多个线程可见之前已完成。
于 2012-12-08T07:04:29.960 回答