iOS 单例浅谈

原帖地址:http://blog.csdn.net/iosevanhuang/article/details/13278323

尊重原帖,请勿盗版。感谢原作者!


“单例模式”是我在iOS中最常使用的设计模式之一。单例模式不需要传递任何参数,就有效地解决了不同代码间的数据共享问题。


背景

单例类是一个非常重要的概念,因为它们表现出了一种十分有用的设计模式。单例类的应用贯穿于整个iPhone SDK中。例如,UIApplication类有一个方法叫sharedApplication,从任何地方调用这个方法,都将返回与当前正在运行的应用程序相关联的UIApplication实例。

博主补充:单例类保证了应用程序的生命周期中有且仅有一个该类的实例对象,而且易于外界访问。


实现

你可以用以下代码实现一个Objective-C的单例类(ARC模式下,非ARC模式下面会讲到):

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
           
           
#import <foundation/Foundation.h>
@interface MyManager : NSObject {
NSString * someProperty ;
}
@property ( nonatomic , retain ) NSString * someProperty ;
+ ( id ) sharedManager ;
@end
 来自CODE的代码片
MyManager.h

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
           
           
#import "MyManager.h"
@implementation MyManager
@synthesize someProperty ;
#pragma mark Singleton Methods
+ ( id ) sharedManager {
static MyManager * sharedMyManager = nil ;
static dispatch_once_t onceToken ;
dispatch_once ( & onceToken , ^ {
sharedMyManager = [[ self alloc ] init ];
});
return sharedMyManager ;
}
- ( id ) init {
if ( self = [ super init ]) {
someProperty = [[ NSString alloc ] initWithString : @"Default Property Value" ];
}
return self ;
}
- ( void ) dealloc {
// 永远不要调用这个方法
}
@end
 来自CODE的代码片
MyManager.m

在这里我们定义了一个静态变量sharedMyManager,然后仅初始化一次该变量。这里使用了dispatch_once以保证该变量只被GCD初始化一次。操作系统将保证这是线程安全的。

如果不使用GCD,你可以使用以下代码:

 1
 2
 3
 4
 5
 6
 7
 8
           
           
+ ( id ) sharedManager {
static MyManager * sharedMyManager = nil ;
@synchronized ( self ) {
if ( sharedMyManager == nil )
sharedMyManager = [[ self alloc ] init ];
}
return sharedMyManager ;
}
 来自CODE的代码片
Non-GCD-based-code.m

接下来,当你需要使用这个单例对象时,你只要这样调用就可以了:
 1
            
            
MyManager * sharedManager = [ MyManager sharedManager ];
 来自CODE的代码片
snippet_file_0.m

我在我的代码中广泛使用单例类,比如创建一个单例类来处理CoreLocation或CoreData功能。

非ARC代码
虽然我并不那么推荐,但是如果你要使用非ARC环境的话,你应该使用以下代码:
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
           
           
#import "MyManager.h"
static MyManager * sharedMyManager = nil ;
@implementation MyManager
@synthesize someProperty ;
#pragma mark Singleton Methods
+ ( id ) sharedManager {
@synchronized ( self ) {
if ( sharedMyManager == nil )
sharedMyManager = [[ super allocWithZone : NULL ] init ];
}
return sharedMyManager ;
}
+ ( id ) allocWithZone: ( NSZone * ) zone {
return [[ self sharedManager ] retain ];
}
- ( id ) copyWithZone: ( NSZone * ) zone {
return self ;
}
- ( id ) retain {
return self ;
}
- ( unsigned ) retainCount {
return UINT_MAX ; // 表示该对象永远不应被释放
}
- ( oneway void ) release {
// 从不释放
}
- ( id ) autorelease {
return self ;
}
- ( id ) init {
if ( self = [ super init ]) {
someProperty = [[ NSString alloc ] initWithString : @"Default Property Value" ];
}
return self ;
}
- ( void ) dealloc {
// 从不调用该方法
[ someProperty release ];
[ super dealloc ];
}
@end
 来自CODE的代码片
MyManager-non-ARC.m

博主:这里的单例都是懒汉式单例,当单例对象的获取方法第一次被调用时创建单例对象。而在类被加载时就创建单例对象叫做饿汉式单例。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值