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

Objective-c单例模式的正确写法

2015-11-20 22:05 351 查看
Objective-c单例模式的正确写法

单例模式在iOS开发中可能算是最常用的模式之一了,但是由于oc本身的语言特性,想要写一个正确的单例模式相对来说比较麻烦,这里我就抛砖引玉来聊一聊iOS中单例模式的设计思路。关于单例模式更多的介绍请参考这篇文章。

单例顾名思义就是说一个类的实例只能有一个,在java、C++这类语言中,可以通过将构造函数私有化来避免对象的重复创建,但是objective-c却不能够这样做,我们需要通过其他机制来达到这个目的。一般情况下,可能我们写的单例模式是这样的:

?
1

2

3

4

5

6

7

8

9

10

11

12

13

14

1516

17

18

19

20

21

22

23

24

25

26

27
#
import

<foundation foundation.h=
""
>


@interface

Singleton : NSObject


+(instancetype)
shareInstance ;


@end


#
import

"Singleton.h"


@implementation

Singleton


static

Singleton* _instance = nil;


+(instancetype)
shareInstance


{


static

dispatch_once_t onceToken ;


dispatch_once(&onceToken,
^{


_instance
= [[self alloc] init] ;


})
;




return

_instance ;


}


@end
</foundation>


具体使用:

?
1

2

3

4

5

6

7

8

9

10

11

12

13

14

1516

17

18
#
import

<foundation foundation.h=
""
>


#
import

"Singleton.h"


int

main(
int

argc,
const
char
* argv[]) {


@autoreleasepool

{




Singleton*
obj1 = [Singleton shareInstance] ;


NSLog(@
"obj1
= %@."
,
obj1) ;




Singleton*
obj2 = [Singleton shareInstance] ;


NSLog(@
"obj2
= %@."
,
obj2) ;




//


Singleton*
obj3 = [[Singleton alloc] init] ;


NSLog(@
"obj3
= %@."
,
obj3) ;


}


return

0
;


}</foundation>


输出结果为 :

?
1

2

3
2014
-
12
-
15

16
:
06
:
28.344

ObjcSingleton[
8847
:
303
]
obj1 = <singleton:
0x1001086e0
=
""
>.


2014
-
12
-
15

16
:
06
:
28.346

ObjcSingleton[
8847
:
303
]
obj2 = <singleton:
0x1001086e0
=
""
>.


2014
-
12
-
15

16
:
06
:
28.346

ObjcSingleton[
8847
:
303
]
obj3 = <singleton:
0x100103940
=
""
>.</singleton:></singleton:></singleton:>


可以看到,当我们调用shareInstance方法时获取到的对象是相同的,但是当我们通过alloc和init来构造对象的时候,得到的对象却是不一样的。
那么问题就来了,我们通过不同的途径得到不同的对象,显然是不行的。我们必须要确保对象的唯一性,所以我们就需要封锁用户通过alloc和init以及copy来构造对象这条道路。
我们知道,创建对象的步骤分为申请内存(alloc)、初始化(init)这两个步骤,我们要确保对象的唯一性,因此在第一步这个阶段我们就要拦截它。当我们调用alloc方法时,oc内部会调用allocWithZone这个方法来申请内存,我们覆写这个方法,然后在这个方法中调用shareInstance方法返回单例对象,这样就可以达到我们的目的。拷贝对象也是同样的原理,覆写copyWithZone方法,然后在这个方法中调用shareInstance方法返回单例对象。看代码吧:

?
1

2

3

4

5

6

7

8

9

10

11

12

13

14

1516

17

18

19

20

21

22

23

24

25

26

27
#
import

"Singleton.h"


@implementation

Singleton


static

Singleton* _instance = nil;


+(instancetype)
shareInstance


{


static

dispatch_once_t onceToken ;


dispatch_once(&onceToken,
^{


_instance
= [[
super

allocWithZone:NULL] init] ;


})
;




return

_instance ;


}


+(id)
allocWithZone:(struct _NSZone *)zone


{


return

[Singleton shareInstance] ;


}


-(id)
copyWithZone:(struct _NSZone *)zone


{


return

[Singleton shareInstance] ;


}


@end


再看看效果如何:

?
1

2

3

4

5

6

7

8

9

10

11

12

13

14

1516

17

18

19

20

21

22

23
main
:


#
import

<foundation foundation.h=
""
>


#
import

"Singleton.h"


int

main(
int

argc,
const
char
* argv[]) {


@autoreleasepool

{




Singleton*
obj1 = [Singleton shareInstance] ;


NSLog(@
"obj1
= %@."
,
obj1) ;




Singleton*
obj2 = [Singleton shareInstance] ;


NSLog(@
"obj2
= %@."
,
obj2) ;




//


Singleton*
obj3 = [[Singleton alloc] init] ;


NSLog(@
"obj3
= %@."
,
obj3) ;




Singleton*
obj4 = [[Singleton alloc] init] ;


NSLog(@
"obj4
= %@."
,
[obj4 copy]) ;


}


return

0
;


}</foundation>


输出结果:

?
1

2

3

4
2014
-
12
-
15

16
:
11
:
24.734

ObjcSingleton[
8979
:
303
]
obj1 = <singleton:
0x100108720
=
""
>.


2014
-
12
-
15

16
:
11
:
24.735

ObjcSingleton[
8979
:
303
]
obj2 = <singleton:
0x100108720
=
""
>.


2014
-
12
-
15

16
:
11
:
24.736

ObjcSingleton[
8979
:
303
]
obj3 = <singleton:
0x100108720
=
""
>.


2014
-
12
-
15

16
:
11
:
24.736

ObjcSingleton[
8979
:
303
]
obj4 = <singleton:
0x100108720
=
""
>.</singleton:></singleton:></singleton:></singleton:>


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  iOS 单例