在iOS中單例的實現與使用
單例在我們開發中是最常用的設計模式,在iOS中也是如此。單例可以保證某個類的執行個體在程式中是唯一的,便於進行資源和資料的共用。使用的設計原則是單一職責原則。我們來看看在iOS中本身內建的類或者方法哪些使用了單例的模式:
(1)UIAccelerometer類和sharedAccelerometer方法,一般如果方法名中有shared這樣的詞,就可以認為這是一個可以整個應用程式共用的執行個體變數,一般是使用了單例。
(2)UIApplication類和sharedApplication方法,我們一般使用該方法來建立全域變數。
(3)NSBundle類和mainBundle方法。
(4)NSFileManager類和defaultManager方法。
(5)NSNotificationCenter類和defaultManager方法。其中NSNotificationCenter也實現了觀察者模式。
(6)NSUserDefaults類和defaultUser方法。
今天我們嘗試自己來實現一個單例:
(1)建立一個普通的類,假設名字為Singleton. 在Singleton.h中聲明一個類方法,到時候使用該類方法(注意:一定是類方法,而不是執行個體方法)可以建立該類的唯一的一個執行個體:
#import @class Singleton;@interface Singleton : NSObject// "+" 表示類的方法,由類調用+(Singleton *)sharedInstance;@end
(2)在Singleton.m中需要實現sharedInstance方法和你其他的商務邏輯:
#import "Singleton.h"// 用static聲明一個類的靜態執行個體;static Singleton *_sharedInstance = nil;@implementation Singleton/** * 1.使用類方法產生這個類唯一的執行個體; */+(Singleton *)sharedInstance{ if (!_sharedInstance) { _sharedInstance =[[self alloc]init]; } return _sharedInstance;}@end
注意:一定要聲明一個static的靜態變數。以後建立類的唯一執行個體就使用sharedInstance方法,而不是使用alloc ,init.
(3)我們使用一個簡單的demo來示範一下單例:
#import "RootVC.h"#import "Singleton.h"@interface RootVC ()@end@implementation RootVC- (void)viewDidLoad{ [super viewDidLoad]; [self testSigleTon];}-(void)testSigleTon{ //單例的結果就是,調用類方法,只返回一個共有的對象 /** * single和single2是同一個對象; 因為返回的資料是一個靜態變數,全域唯一; */ Singleton *single = [Singleton sharedInstance]; Singleton *single2 = [Singleton sharedInstance]; if (single == single2) { NSLog(@"single == single2"); } NSLog(@"single地址:%@",single); NSLog(@"single2地址:%@",single2);}@end
(4)輸出結果如下:
。
可以看到,兩個對象的記憶體位址是一樣的,表示這兩個對象其實是同一個對象,單例也就實現了。這是單例最普遍也是最簡單的實現方式,在項目中會經常用到,在不涉及多線程的情況下是完全正確的。但是,我們再多想一想,在多線程開發中,這種實現方式是否安全呢?那麼應該如何?。我會在之後的部落格中進行介紹。