ios之單例模式


原帖地址:http://www.galloway.me.uk/tutorials/singleton-classes/

本文為博主自行翻譯,轉載請注明出處: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
博主:這里的單例都是懶漢式單例,當單例對象的獲取方法第一次被調用時創建單例對象。而在類被加載時就創建單例對象叫做餓漢式單例。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM