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

标签 ios objective-c singleton initialization private-members

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

我需要一个类的单例,它既有公共(public)变量也有私有(private)变量。目前,这是我对此类的实现:

@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];
}

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

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

谢谢

最佳答案

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

Another issue I'd like to make clear about singleton is: will this generate a memory leak?

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

Is the use of singletons actually recommended in iOS?

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

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

关于ios - iOS 5+ 中的 Objective-C 单例模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15463761/

相关文章:

构造函数中的 C++ 单例

language-agnostic - 单例在编程中的用途

ios - NSURLConnection 委托(delegate)连接 :willCacheResponse: randomly called

objective-c - 动画在 iOS6 中工作,在 iOS5 中有错误

objective-c - 使用常量 NSString 作为 NSUserDefaults 的键

ios - 将 Json 值传递给其他 ViewController?

design-patterns - 单例模式可以用于多个(但固定)数量的实例吗

ios - ARkit图像识别和图像的AR可视化

objective-c - 使用 iOS Dropbox SDK 分块上传核心数据

ios - 在两个 View Controller Swift IOS 之间传递数据