單例模式在iOS開發過程中經常用到,蘋果提供過objective c單例的比較官方的寫法:
static MyGizmoClass *sharedGizmoManager = nil; + (MyGizmoClass*)sharedManager{ @synchronized(self) { if (sharedGizmoManager == nil) { [[self alloc] init]; // assignment not done here } } return sharedGizmoManager;} + (id)allocWithZone:(NSZone *)zone{ @synchronized(self) { if (sharedGizmoManager == nil) { sharedGizmoManager = [super allocWithZone:zone]; return sharedGizmoManager; // assignment and return on first allocation } } return nil; //on subsequent allocation attempts return nil} - (id)copyWithZone:(NSZone *)zone{ return self;} - (id)retain{ return self;} - (unsigned)retainCount{ return UINT_MAX; //denotes an object that cannot be released} - (void)release{ //do nothing} - (id)autorelease{ return self;}
現在iOS5之後普遍使用了ARC技術,原來這個寫法就顯得很累贅了,release已經不使用了。
咱們可以結合GCD來實現單例模式:
+ (id)sharedInstance{ static dispatch_once_t pred = 0; __strong static id _sharedObject = nil; dispatch_once(&pred, ^{ _sharedObject = [[self alloc] init]; // or some other init method }); return _sharedObject;}
使用dispatch_once,這個方法的意思是在應用程式生命週期內,這方法只執行一次,這就是ARC下結合GCD的一個單例的代碼
因為我們可能需要多個單例的類,每個都寫一次比較麻煩,可以更方便一些,把這些代碼寫成宏的形式,只需要傳入類名就可以建立一個單例的類了。
通過傳入類名建立標頭檔中單例方法的名稱:
#define DEFINE_SINGLETON_FOR_HEADER(className) \\+ (className *)shared##className;
通過傳入類名建立單例方法的實現
#define DEFINE_SINGLETON_FOR_CLASS(className) \\+ (className *)shared##className { \static className *shared##className = nil; \static dispatch_once_t onceToken; \dispatch_once(&onceToken, ^{ \shared##className = [[self alloc] init]; \}); \return shared##className; \}
使用宏:
在項目中建立了一個類testSingleton,並且有.h 和.m檔案。
.h
.m中的代碼:
#import "testSingleton.h"@implementation testSingletonDEFINE_SINGLETON_FOR_CLASS(testSingleton)@end
#define DEFINE_SINGLETON_FOR_HEADER(className) \\+ (className *)shared##className;#define DEFINE_SINGLETON_FOR_CLASS(className) \\+ (className *)shared##className { \static className *shared##className = nil; \static dispatch_once_t onceToken; \dispatch_once(&onceToken, ^{ \shared##className = [[self alloc] init]; \}); \return shared##className; \}#import <Foundation/Foundation.h>@interface testSingleton : NSObjectDEFINE_SINGLETON_FOR_HEADER(testSingleton);@end
你可以把宏單獨放到專案管理宏的檔案中。這裡是為了方便示範放到和testSingleton.h檔案了。
擷取單例:
- (void)test{ testSingleton *testShare = [testSingleton sharedtestSingleton];}
有什麼不明白的可以留言交流。
容芳志 (http://blog.csdn.net/totogo2010)
本文遵循“署名-非商業用途-保持一致”創作公用協議