您的位置:首页 > 移动开发 > Objective-C

objective-c 单例模式详解

2014-03-05 16:47 363 查看
最近在项目中需要用到单例模式(singleton),于是对谷歌了一些资料发现objective-c中的单例不是想象中的,apple官方文档建议并非如此,代码量是我好几倍,但是既然官方建议一定是有道理的,谷歌了写资料,多数都是建议这么使用,却没人对此做详解

因为没理解透,用着不踏实,所以决定做些调试,了解透彻!

按照一般的思路,如下

01
static
MyClass
*
class
=
nil;
02
03
@implementation
MyClass
04
05
+(MyClass
*)sharedMyClass{
06
07
if
(!
class
)
{
08
09
class
=
[[selfalloc]init];
10
11
}
12
13
return
class
;
14
15
}
16
17
@end
调试发现

MyClass*A=[[MyClassalloc]init];

NSLog(@"A:%@",A);

MyClass*B=[MyClasssharedMyClass];

NSLog(@"B:%@",B);

打印出的是

A:<MyClass:0x6c72d30>

B:<MyClass:0x6a87e60>

不是一个内存地址,也就是不是同一个实体

官方如下方式实现

01
static
MyClass
*
class
=
nil;
02
03
@implementation
MyClass
04
05
+(MyClass
*)sharedMyClass{
06
@synchronized
(self){
//为了确保多线程情况下,仍然确保实体的唯一性
07
if
(!
class
)
{
08
[[self
alloc]init];
//该方法会调用
allocWithZone
09
}
10
}
11
return
class
;
12
}
13
14
15
+(id)allocWithZone:(NSZone
*)zone{
16
@synchronized
(self){
17
if
(!
class
)
{
18
class
=
[superallocWithZone:zone];
//确保使用同一块内存地址
19
return
class
;
20
}
21
}
22
return
nil;
23
}
24
25
-
(id)copyWithZone:(NSZone*)zone;{
26
return
self;
//确保copy对象也是唯一
27
}
28
29
-(id)retain{
30
return
self;
//确保计数唯一
31
}
32
33
-
(unsigned)retainCount
34
{
35
return
UINT_MAX;
//装逼用的,这样打印出来的计数永远为-1
36
}
37
38
-
(id)autorelease
39
{
40
return
self;
//确保计数唯一
41
}
42
43
-
(oneway
void
)release
44
45
{
46
//重写计数释放方法
47
}
48
49
@end
再调试

MyClass*A=[[MyClassalloc]init];

NSLog(@"A:%@",A);

MyClass*B=[MyClasssharedMyClass];

NSLog(@"B:%@",B);

MyClass*C=[Acopy];

NSLog(@"C:%@",C);

打印出的是

A:<MyClass:0x6a1e130>

B:<MyClass:0x6a1e130>

C:<MyClass:0x6a1e130>

都是指向同一块内存地址

答案已经出来了

apple建议的方式显然真正的确保了实体的唯一性
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: