0

有时我想在对象的生命周期中执行一次代码。过去我设置了一个BOOL可以检查的属性,但这有点尴尬。Objective-C 中是否有一些内置的东西可以优雅地完成这个任务?有点像dispatch_once,但与对象相关,而不是应用程序的生命周期。

4

2 回答 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 回答