目标c单例dispatch_once实现更好?
Posted
技术标签:
【中文标题】目标c单例dispatch_once实现更好?【英文标题】:objective c singleton dispatch_once implementation is better? 【发布时间】: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 的含义,并且不要按照惯例对其进行任何内存管理。但是,您仍然没有办法真正阻止它吗?
【参考方案1】:
为什么不把两者结合起来呢?
使用您列出的函数而不是 Apple 的 + (MyGizmoClass*)sharedManager
函数,但实现所有 allocWithZone
、copyWithZone
、retain
、retainCount
、release
和 autorelease
覆盖。
这里有更多讨论:What should my Objective-C singleton look like?
【讨论】:
为什么不呢?因为它会与 ARC 发生冲突。【参考方案2】:如果你希望它是一个单例,并且你担心调用 alloc/init 会发生什么:不要这样做!就那么简单。
有种情况,比如 NSFileManager,你有一个单例 [NSFileManager defaultManager] 但你也可以有单独的 NSFileManager* 对象。所以这很容易实现。
【讨论】:
以上是关于目标c单例dispatch_once实现更好?的主要内容,如果未能解决你的问题,请参考以下文章
(一二三)基于GCD的dispatch_once实现单例设计
GCD的同步异步串行并行NSOperation和NSOperationQueue一级用dispatch_once实现单例
iOS开发-91GCD的同步异步串行并行NSOperation和NSOperationQueue一级用dispatch_once实现单例(转载)