iOS 5+中的Objective-C单例模式

App*_*Dev 12 singleton initialization objective-c private-members ios

我一直在阅读很多关于如何在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];
}
Run Code Online (Sandbox Code Playgroud)

这应该是推荐的方式吗?我应该如何初始化实例变量public和private?

我想说明单例的另一个问题是:这会产生内存泄漏吗?在iOS中实际推荐使用单身人士吗?

谢谢

Rob*_*ier 12

以上是正确的,以及@miho关于包含sharedInstance方法内部静态对象的注释.但是没有理由超越+allocWithZone:.ObjC中的单身人士通常是"共享的",而不是强迫的.您可以自由创建"单身"的其他实例.如果创建其他实例是非法的,那么你应该init执行一个NSAssert而不是愚弄调用者+allocWithZone:.如果你的单身是可变的(大多数是),你绝对不应该这样覆盖+allocWithZone:.

我想说明单例的另一个问题是:这会产生内存泄漏吗?

不会.此对象永远不会发布,但始终可以访问.那不是泄密.

在iOS中实际推荐使用单身人士吗?

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

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

  • 啊.当你退出覆盖`allocWithZone:`(你几乎不应该覆盖)时,这将不再是一个问题. (2认同)

GoZ*_*ner 3

在 Xcode 中,在“搜索文档”下输入“创建单例实例”。有很多结果(但是页面底部上面的链接有示例代码)。

  • 不要轻易使用该页面底部的代码。正如它所指出的,它专门用于创建“严格的单例”。这些在可可中极为罕见。共享单例是常态,不需要大部分代码。该代码片段在新的 Cocoa 开发人员中引起了很多困惑。我建议忽略它;您不太可能遇到它有用的情况。 (9认同)