ios - +[NSObject initialize] 内部的 dispatch_once 是否矫枉过正?

标签 ios objective-c concurrency grand-central-dispatch objective-c-runtime

如果我在 +[NSObject initialize] 中创建一个单例,我是否需要像这样将我的代码放在 dispatch_once block 中?

static NSObject * Bar;
@implementation Foo
+ (void)initialize {
  if (self == [Foo class]) {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
      Bar = [NSObject new];
    });
  }
}
@end

编辑

我很担心这一点,因为我想确保在调用 +[Foo initialize] 后所有线程都能看到我设置了 Bar。文档说 +[NSObject initialize] 是线程安全的,但这是否意味着它是内存安全的?

最佳答案

你的直接问题的答案是你不需要 dispatch_once,但你确实需要你在那里的类检查,因为 +initialize 将被调用 once per "non-implementing subclass" as well .对于您关心的特定类 (Foo),它只会被调用一次,因此 dispatch_once 是无关紧要的。回复:线程安全,+initialize 方法将在任何其他方法被分派(dispatch)到类(或其实例)之前完成。

但是,您没有描述所需的访问模式,因此根据您的需要,您可能希望做相反的事情——如果您希望子类也可以访问 Bar,那么这将是脆弱的;如果子类在 Foo 本身之前被初始化,那么类检查将阻止 Bar 被创建。如果您想要这种行为,则使用 dispatch_once 但删除类检查——这通常会允许 Bar 第一次创建 Foo或其任何子类都已初始化。 (注意:除非子类 also overrides +initialize, of course 。)

关于ios - +[NSObject initialize] 内部的 dispatch_once 是否矫枉过正?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18835992/

相关文章:

ios - 在 iOS 中使用照片框架获取图像路径时 UI 被阻塞

ios - 将 localforage-cordovasqlitedriver 安装到我的项目中时缺少 localforage.js 文件

ios - 没有进入的for循环

objective-c - xcode:无论输入是什么,TextField.text 都返回 nil:[New Referencing Outlet]?

c# - 为什么首先将多个任务存储在 var 中然后等待它们会有所不同?

ios - View 的透明背景 PresentViewController

objective-c - UITableView/UITabBarController : trying to figure out a method to pass a variable to my destination controller when a row is selected

ios - Swift 中的 ARC 不可用方法

Java - 在 JPanel 中获取选择的选项而不进行轮询

java - static 是否在 JMM 上下文中提供额外的保证?