您的位置:首页 > 移动开发 > IOS开发

IOS 中的单例模式

2014-09-30 03:36 169 查看
转自 http://www.galloway.me.uk/tutorials/singleton-classes/


Singletons in Objective-C

One of my most used design patterns when developing for iOS is the singleton pattern. It’s an extremely powerful way to share data between different parts of code without
having to pass the data around manually. More about the singleton pattern and other patterns can be found in this excellent book:


Background

Singleton classes are an important concept to understand because they exhibit an extremely useful design pattern. This idea is used throughout the iPhone SDK, for example, UIApplication has a method called sharedApplication which when called from anywhere will
return the UIApplication instance which relates to the currently running application.


How to implement

You can implement a singleton class in Objective-C using the following code:
MyManager.h

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

MyManager.m

1
2
3
4
5
6
7
8
9
10
1112
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 {
// Should never be called, but just here for clarity really.
}

@end

What this does is it defines a static variable (but only global to this translation unit)) called
sharedMyManager
which
is then initialised once and only once in
sharedManager
.
The way we ensure that it’s only created once is by using the
dispatch_once
method
from Grand Central Dispatch (GCD). This is thread safe and handled entirely by the OS for you so
that you don’t have to worry about it at all.

However, if you would rather not use GCD then you should use the following code for
sharedManager
:
Non-GCD based code

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;
}

Then you can reference the singleton from anywhere by calling the following function:
MyManager *sharedManager = [MyManager sharedManager];


I’ve used this extensively throughout my code for things such as creating a singleton to handle CoreLocation or CoreData functions.


Non-ARC code

Not that I recommend it, but if you are not using Automatic Reference Counting (ARC), then you should use the following code:
MyManager.h non-ARC

1
2
3
4
5
6
7
8
9
10
1112
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; //denotes an object that cannot be released
}
- (oneway void)release {
// never release
}
- (id)autorelease {
return self;
}
- (id)init {
if (self = [super init]) {
someProperty = [[NSString alloc] initWithString:@"Default Property Value"];
}
return self;
}
- (void)dealloc {
// Should never be called, but just here for clarity really.
[someProperty release];
[super dealloc];
}

@end

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