原帖地址: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
|
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
|
在这里我们定义了一个静态变量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
];
|
我在我的代码中广泛使用单例类,比如创建一个单例类来处理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
|
博主:这里的单例都是懒汉式单例,当单例对象的获取方法第一次被调用时创建单例对象。而在类被加载时就创建单例对象叫做饿汉式单例。