Cocoa dispatch_once每个实例

时间:2014-08-08 10:29:11

标签: ios objective-c cocoa

如何使用displatch_once,因此每个实例生命周期执行一次给定代码

等效的是在对象中有一个属性,并像这样使用它

- (void)viewWillAppear:(..).. {

   ...

   if (self.isDisplatched == NO) {
      ...
      self.isDisplatched = YES;
   }

}

但我不想使用额外的属性,但是dispatch_once_t或者是simmilar

2 个答案:

答案 0 :(得分:6)

您的要求无法满足。 dispatch_once只能用于以前从未写过的内存,而且你无法用实例变量来保证这一点。 Greg Parker says so,他是那个知道的人。

相反,请使用问题中的代码,但将其包装在@synchronized块中。

如果您真的想避免添加实例变量,可以使用单独的单例来管理可变集。您必须使用它注册实例并在重新分配时删除它们。确保这个助手类只包含弱引用;请参阅NSMapTableNSMapTableWeakMemory

答案 1 :(得分:1)

对于那些好奇并且作为额外提示的人,对我而言,这种方法对此有用:

class SomeVC : UIViewController {
    private var token: dispatch_once_t = 0

    public override func viewDidAppear(animated: Bool) {
        super.viewDidAppear(animated)

        dispatch_once(&token) { () -> Void in
            self.doSomethingOnce()
        }

    }
}

通过不声明静态var,它具有预期的行为。话虽如此,对于任何严肃的项目来说,这绝对不是推荐的,因为在Docs中(正如你的说法所说),它声明:

  

谓词必须指向存储在全局或静态范围内的变量。使用带有自动或动态存储的谓词(包括Objective-C实例变量)的结果是未定义的。

如果我们不想遇到任何未来奇怪的错误和未定义的行为,我会坚持苹果所说的。但玩这些东西仍然很好,不是吗? =)