有没有一种优雅的方法在Objective-C中的对象的生命周期中执行一次代码?

时间:2012-12-08 06:58:51

标签: objective-c c cocoa

偶尔我想在对象的生命周期中执行一次代码。在过去,我已经设置了BOOL属性,我可以检查,但这有点尴尬。是否内置了Objective-C,优雅地实现了这一点?有点像dispatch_once,但与对象有关,而不是应用程序的生命周期。

2 个答案:

答案 0 :(得分:2)

根据apple documentation dispatch_once,在这种情况下不应该使用!

  

谓词必须指向存储在全局或静态范围内的变量。 使用带自动或动态存储的谓词的结果未定义。

另一种方法是使用atomic operations。这样,还可以确保代码仅在对象的生命周期内执行一次。

@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或类似的东西来包装整个东西,然后使用原子操作毫无意义。

答案 1 :(得分:1)

您可以使用dispatch_once_t实例变量来执行此操作。如果您要在多个线程上使用此对象,请注意细微的线程问题(不是特定于dispatch_once)。在init结束时需要一个内存屏障,以确保在对象对多个线程可见之前已完成ivar的初始化。