Objective-C中单例模式的实现

移动开发 iOS
单例模式是对象的创建模式之一,此外还包括工厂模式。单例模式的三个特点:1、该类只有一个实例。2、该类自行创建该实例(在该类内部创建自身的实例对象)。3、向整个系统公开这个实例接口。

单例模式在Cocoa和Cocoa Touch中非常常见。比如这两个,[UIApplication sharedApplication]和[NSApplication sharedApplication],大家应该都见过。但是我们应该如何在代码中实现一个单例模式呢?

1.如果你对苹果的文档很熟悉的话,你一定知道,在Cocoa Foundamentals Guide中有一段实现单例模式的示例代码。大致如下

  1. /* Singleton.h */ 
  2. #import <Foundation/Foundation.h> 
  3. @interface Singleton : NSObject 
  4. + (Singleton *)instance; 
  5. @end 
  6.       
  7. /* Singleton.m */ 
  8. #import "Singleton.h" 
  9. static Singleton *instance = nil; 
  10.       
  11. @implementation Singleton 
  12. + (Singleton *)instance { 
  13. if (!instance) { 
  14.     instance = [[super allocWithZone:NULL] init]; 
  15.     return instance; 
  16. + (id)allocWithZone:(NSZone *)zone { 
  17.     return [self instance]; 
  18. - (id)copyWithZone:(NSZone *)zone { 
  19.     return self; 
  20. - (id)init { 
  21.      if (instance) { 
  22.        return instance; 
  23.     self = [super init]; 
  24.     return self; 
  25. - (id)retain { 
  26.     return self; 
  27. - (oneway void)release { 
  28.     // Do nothing 
  29. - (id)autorelease { 
  30.     return self; 
  31. - (NSUInteger)retainCount { 
  32.     return NSUIntegerMax; 
  33. @end 

这是一种很标准的Singleton实现,中规中矩。不过这种实现并不是线程安全的。所以各路大神都各显神威,给出了多种单例模式的实现。

2.Matt Gallagher在博客中放出了一个Macro,用来实现单例模式。虽然是一个宏定义的代码,但是具体实现还是很清楚的。代码如下:

  1. //  SynthesizeSingleton.h 
  2. //  CocoaWithLove 
  3. //  Created by Matt Gallagher on 20/10/08. 
  4. //  Copyright 2009 Matt Gallagher. All rights reserved. 
  5. //  Permission is given to use this source code file without charge in any 
  6. //  project, commercial or otherwise, entirely at your risk, with the condition 
  7. //  that any redistribution (in part or whole) of source code must retain 
  8. //  this copyright and permission notice. Attribution in compiled projects is 
  9. //  appreciated but not required. 
  10. // 
  11. #define SYNTHESIZE_SINGLETON_FOR_CLASS(classname) \ 
  12. static classname *shared##classname = nil; \ 
  13. + (classname *)shared##classname \ 
  14. { \ 
  15. @synchronized(self) \ 
  16.     { \ 
  17.          if (shared##classname == nil) \ 
  18.          { \ 
  19.              shared##classname = [[self alloc] init]; \ 
  20.           } \ 
  21.      } \ 
  22.       return shared##classname; \ 
  23. } \ 
  24. + (id)allocWithZone:(NSZone *)zone \ 
  25. { \ 
  26. @synchronized(self) \ 
  27.      { \ 
  28.         if (shared##classname == nil) \ 
  29.            { \ 
  30.               shared##classname = [super allocWithZone:zone]; \ 
  31.               return shared##classname; \ 
  32.             } \ 
  33.       } \ 
  34.     return nil; \ 
  35. } \ 
  36. - (id)copyWithZone:(NSZone *)zone \ 
  37. { \ 
  38.     return self; \ 
  39. } \ 
  40. - (id)retain \ 
  41. { \ 
  42.     return self; \ 
  43. } \ 
  44. - (NSUInteger)retainCount \ 
  45. { \ 
  46.     return NSUIntegerMax; \ 
  47. } \ 
  48. - (void)release \ 
  49. { \ 
  50. } \ 
  51. - (id)autorelease \ 
  52. { \ 
  53.     return self; \ 

是不是感觉这两种方法很拖沓,别担心,后面将介绍简单的实现单利的方法!

#p#

3.然而,eschaton则觉得这些实现都太繁琐了,他给出的实现如下:

  1. @interface SomeManager : NSObject 
  2. + (id)sharedManager; 
  3. @end 
  4.  
  5. /* 非线程安全的实现 */ 
  6. @implementation SomeManager 
  7. + (id)sharedManager { 
  8. static id sharedManager = nil; 
  9. if (sharedManager == nil) { 
  10.     sharedManager = [[self alloc] init]; 
  11.     return sharedManager; 
  12. @end 
  13.  
  14. /* 线程安全的实现 */ 
  15. @implementation SomeManager 
  16. static id sharedManager = nil; 
  17. + (void)initialize { 
  18.       if (self == [SomeManager class]) { 
  19.       sharedManager = [[self alloc] init]; 
  20.     } 
  21. + (id)sharedManager { 
  22.     return sharedManager; 
  23. @end 

关于为什么上述代码就能实现单例模式,以及关于线程安全问题的考量,请参考他的博客

4.最后介绍一个比较现代的单例模式实现。为什么说现代呢?因为这种实现利用了GCD(Grand Central Dispatch)和ARC(Automatic Reference Counting)。核心代码如下:

  1. + (id)sharedInstance 
  2.     static dispatch_once_t pred = 0; 
  3.     __strong static id _sharedObject = nil; 
  4.     dispatch_once(&pred, ^{ 
  5.     _sharedObject = [[self alloc] init]; // or some other init method 
  6.     }); 
  7.     return _sharedObject; 

作者还写了一个宏(gist)来方便使用,大家可以阅读作者的博文A note on Objective-C singletons了解详情。

大多数情况下,Apple官方文档里的单例模式的示例代码实现已经够用了。虽然它最繁琐,但是也是本文介绍的几种单例模式中最容易理解的一个。至于其他的实现就留给读者们根据需要选择和应用了。

责任编辑:闫佳明 来源: oschina
相关推荐

2013-06-20 10:40:32

Objective-C实现截图

2011-07-25 10:03:06

Objective-C 委托

2011-07-19 17:24:31

Objective-C 对象

2015-07-08 16:07:19

iOSObjective-C

2011-08-04 15:52:48

Objective-C HTML

2011-08-15 17:47:13

Objective-CisMemberOfC

2011-08-04 10:57:33

Objective-C C语言 BOOL

2011-05-11 11:20:26

Objective-C

2013-03-27 12:54:00

iOS开发Objective-C

2011-05-11 15:58:34

Objective-C

2011-06-28 15:18:45

Qt 单例模式

2015-07-08 10:51:27

Objective-CRuntime

2012-01-11 09:15:45

Objective-C

2011-08-10 18:07:29

Objective-C反射

2011-07-27 16:18:42

Objective-c 协议

2011-08-15 17:06:01

Objective-CNSLog

2011-07-08 18:44:09

Objective-C Self Super

2011-07-20 13:34:37

Objective-C self.

2013-04-11 13:41:30

Objective-CiOS编程

2014-07-29 09:44:35

点赞
收藏

51CTO技术栈公众号