【问题标题】:objective c singleton dispatch_once implementation is better?目标c单例dispatch_once实现更好?
【发布时间】:2012-02-03 14:10:54
【问题描述】:

我看到很多人建议使用 dispatch_once 来做单例:

+(MyClass *)singleton {
    static dispatch_once_t pred;
    static MyClass *shared = nil;

    dispatch_once(&pred, ^{
        shared = [[MyClass alloc] init];
    });
     return shared;
}

为什么它并不真正支持真正的单例,而且人们仍然可以使用 init 来创建实例,甚至在 sharedInstance 上进行释放,这会更好?

Apple 的方法是防止所有这些情况 http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/CocoaFundamentals/CocoaObjects/CocoaObjects.html 我知道它不是线程安全的,但我认为很容易在其中放置一个同步块以使其成为线程安全的。

【问题讨论】:

  • 这很快并且保证无论你怎么称呼它你总是会得到相同的对象。大多数编写单例的人也是消耗它们的人,因此他们(或他们的团队)知道不要尝试分配新实例。
  • 如果你想让你的课程可测试,你仍然可以alloc/init它。使用 Apple 的单例模式,您必须处理在测试之间设置/拆除对象状态的问题。
  • 我认为将一些库/框架分发给其他人使用是很常见的,而这些库/框架将使用单例。是的,大多数开发人员应该了解 sharedInstance 的含义,并且不要按照惯例对其进行任何内存管理。但是,您仍然没有办法真正阻止它吗?

标签: objective-c ios singleton


【解决方案1】:

为什么不把两者结合起来呢?

使用您列出的函数而不是 Apple 的 + (MyGizmoClass*)sharedManager 函数,但实现所有 allocWithZonecopyWithZoneretainretainCountreleaseautorelease 覆盖。

这里有更多讨论:What should my Objective-C singleton look like?

【讨论】:

  • 为什么不呢?因为它会与 ARC 发生冲突。
【解决方案2】:

如果你希望它是一个单例,并且你担心调用 alloc/init 会发生什么:不要这样做!就那么简单。

种情况,比如 NSFileManager,你有一个单例 [NSFileManager defaultManager] 但你也可以有单独的 NSFileManager* 对象。所以这很容易实现。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-06-11
    • 2011-08-08
    • 2021-12-13
    • 2012-02-25
    • 1970-01-01
    • 1970-01-01
    • 2014-07-24
    相关资源
    最近更新 更多