12

我已经阅读了很多关于如何在 Objective-C 中实现单例的线程和博客文章,其中一些可能有点被弃用(2010 年或更早),似乎人们对这个问题有不同的看法。 .. Apple 是否有关于实现单例的文档?我找不到它。如果是这样,有人可以告诉我在哪里吗?

我需要一个具有一些公共和私有变量的类的单例。目前,这是我对此类的实现:

@interface MySingleton ()
   @property (strong, nonatomic) NSString *state;
@end

@implementation MySingleton

@synthesize state = _state;
@synthesize count = _count;

static MySingleton *sharedObject = nil;

+ (MySingleton *)sharedInstance
{
   static dispatch_once_t _singletonPredicate;

   dispatch_once(&_singletonPredicate, ^{
      sharedObject = [[super allocWithZone:nil] init];
   });

   return sharedObject;
}

+ (id)allocWithZone:(NSZone *)zone 
{
   return [self sharedInstance];
}

这应该是推荐的方式吗?我应该如何初始化实例变量,公共的和私有的?

关于单例,我想澄清的另一个问题是:这会产生内存泄漏吗?iOS 中真的推荐使用单例吗?

谢谢

4

5 回答 5

12

以上是正确的,以及@miho 关于在 sharedInstance 方法中包含静态对象的评论。但是没有理由覆盖+allocWithZone:. ObjC 中的单例通常是“共享的”,而不是强制的。您可以自由创建“单例”的其他实例。如果创建其他实例是非法的,那么你应该让initperform anNSAssert而不是在+allocWithZone:. 如果你的单例是可变的(大多数都是),你绝对不应该用+allocWithZone:这种方式覆盖。

关于单例,我想澄清的另一个问题是:这会产生内存泄漏吗?

不,这个对象永远不会被释放,但它总是可以访问的。那不是泄漏。

iOS 中真的推荐使用单例吗?

是的,这是一种非常常见的模式,在 Cocoa 框架中都使用过。也就是说,还有各种其他模式最近开始在开发人员中变得有些流行。依赖注入引起了一些兴趣,尽管我在实践中并不经常看到它。减少对单例的依赖可以提高可测试性,我最近一直在尝试如何在我的代码中消除其中的一些并取得了一些成功。但他们在 Cocoa 有着悠久而自豪的历史,我不认为他们是个问题。

编辑:您的代码中有一个实际错误。你应该打电话[[self alloc] init],而不是[[super alloc] init]。没有理由打电话+allocWithZone:,只需使用+alloc. (...WithZone:方法有用的时代早已过去。)

于 2013-03-17T17:43:06.383 回答
3

在 Xcode 中,在“搜索文档”下输入Creating a Singleton Instance。有很多结果(但上面的链接,在页面底部,有示例代码)。

于 2013-03-17T17:28:42.097 回答
1

是的,这是推荐的方式。我使用它的方式只有一个小区别:我sharedObject在方法中定义 as 静态变量+ (MySingleton *)sharedInstance,因为它不应该从其他任何地方访问该变量,而不是从 getter 方法。

不,您不会造成内存泄漏。当您的应用程序终止时,您的应用程序使用的所有保留内存都将被释放,并且没有其他情况应该释放静态共享实例。在 ARC 之前的区域中,覆盖该release方法以防止意外释放对象是很常见的。

于 2013-03-17T17:36:07.623 回答
0

对单例使用 gcd 的一些警告:

dispatch_once(&_singletonPredicate, ^{
      sharedObject = [[super allocWithZone:nil] init];
   });

如果 init 方法由于某种原因直接或间接地处理了单例对象,就会出现死锁。出于这个原因,我认为编写单例的更合适的方法是通过

+ (void) initialize

方法

于 2013-03-17T19:01:50.103 回答
0

我仍在使用来自CocoaWithLove的单例标题- 可能有点过时但仍然像魅力一样工作。它与此处描述的参考 Apple 文档的功能基本相同,我认为至少 Apple 的文档(本页底部)仍然有效。有些人认为它会无限期地保持有效,因为它是 Apple 建议的官方解决方案。

于 2013-03-17T22:12:23.980 回答