有一段時間沒有發博客了, 恰好如今忙完項目的需求, 如今能夠閒下來寫寫簡書, 順便本身給本身複習鞏固一下知識, 不過我在這裏又要吐槽一句, 項目中遇到了一個單例的問題, 讓我感到很是的蛋疼, 寫這個單例的人只是單純了爲了寫單例而寫單例, 沒有想到會發生什麼, 如今讓咱們一塊兒來看看什麼叫單例吧.git
最後:
若是你有更好的建議或者對這篇文章有不滿的地方, 請聯繫我, 我會參考大家的意見再進行修改, 聯繫我時, 請備註單例模式
若是以爲好的話, 但願你們也能夠打賞一下~嘻嘻~祝你們學習愉快~謝謝~github
Cain(羅家輝)
聯繫方式: zhebushimengfei@qq.com
騰訊QQ: 350116542objective-c
這是一張單例的
UML
圖, 很是簡單明瞭的講解單例類究竟是怎麼回事, 一般單例是用來做爲管理中心, 或者是通知中心, 好比在iOS
當中的NSNotificationCenter
,[[UIApplication sharedApplication] statusBarStyle]
,NSUserDefaults
,[NSFileManager defaultManager]
等等都是單例, 單例類有幾個特徵.學習
- 系統當中只有一個實例
- 易於外界訪問
- 防止子類繼承
- 共享信息
首先, 咱們先來建一個
WorkSpace
, 這樣子方便咱們之後多添加工程, 由於單例模式只是咱們的開始.spa
建立完
WorkingSpace
以後, 咱們就來添加SingletonPattern(單例)
的工程code
如今咱們來建立一個叫
UserInfoManager
單例類繼承
聲明一個類方法用於外界訪問內存
#import <Foundation/Foundation.h> @interface UserInfoManagerCenter : NSObject + (instancetype)managerCenter; @end
接下來咱們去實現這個類方法就行了博客
#import "UserInfoManagerCenter.h" static UserInfoManagerCenter *managerCenter = nil; @implementation UserInfoManagerCenter + (instancetype)managerCenter { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ managerCenter = [[UserInfoManagerCenter alloc] init]; }); return managerCenter; }
看起來, 咱們好像搞定了整個單例模式了, 下面讓咱們來試試效果.it
#import "ViewController.h" #import "UserInfoManagerCenter.h" @interface ViewController () @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; UserInfoManagerCenter *infoManagerCenter = [UserInfoManagerCenter managerCenter]; UserInfoManagerCenter *managerCenter = [UserInfoManagerCenter managerCenter]; NSLog(@"%@", infoManagerCenter); NSLog(@"%@", managerCenter); } @end
打印出來的效果好像是隻有一個, 但實際上並非的, 咱們再來看看
#import "ViewController.h" #import "UserInfoManagerCenter.h" @interface ViewController () @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; UserInfoManagerCenter *infoManagerCenter = [UserInfoManagerCenter managerCenter]; UserInfoManagerCenter *managerCenter = [UserInfoManagerCenter managerCenter]; UserInfoManagerCenter *userInfoManagerCenter = [[UserInfoManagerCenter alloc] init]; NSLog(@"%@", infoManagerCenter); NSLog(@"%@", managerCenter); NSLog(@"%@", userInfoManagerCenter); } @end
發現這個類仍是能夠初始化的, 而且是另外開闢了內存空間來存儲的, 這就很尷尬了, 說好的只有一個實例呢???
我在這裏說一句, 施主莫怕, 等貧僧跳大, 繼續回到單例類當中, 添加幾個判斷就行了
#import "UserInfoManagerCenter.h" static UserInfoManagerCenter *managerCenter = nil; @implementation UserInfoManagerCenter + (instancetype)managerCenter { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ managerCenter = (UserInfoManagerCenter *)@"UserInfoManagerCenter"; managerCenter = [[UserInfoManagerCenter alloc] init]; }); NSString *classString = NSStringFromClass([self class]); if ([classString isEqualToString:@"UserInfoManagerCenter"] == NO) { NSParameterAssert(nil); } return managerCenter; } - (instancetype)init { NSString *userInfomanagerCenter = (NSString *)managerCenter; if ([userInfomanagerCenter isKindOfClass:[NSString class]] && [userInfomanagerCenter isEqualToString:@"UserInfoManagerCenter"]) { if (self = [super init]) { // 這裏直接什麼都不作操做 } return self; } return nil; } @end
口說無憑, 咱們來看看運行效果
這下子, 能夠說明是隻有一個實例了吧, 下面再來看看子類是否能繼承
#import "ViewController.h" #import "UserInfoManagerCenter.h" #import "SubUserInfoManagerCenter.h" @interface ViewController () @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; UserInfoManagerCenter *infoManagerCenter = [UserInfoManagerCenter managerCenter]; UserInfoManagerCenter *managerCenter = [UserInfoManagerCenter managerCenter]; UserInfoManagerCenter *userInfoManagerCenter = [[UserInfoManagerCenter alloc] init]; SubUserInfoManagerCenter *subUserInfoManagerCenter = [SubUserInfoManagerCenter managerCenter]; NSLog(@"%@", infoManagerCenter); NSLog(@"%@", managerCenter); NSLog(@"%@", userInfoManagerCenter); NSLog(@"%@", subUserInfoManagerCenter); } @end
好了, 如今單例所需的
- 易於外界訪問
- 系統當中只有一個實例
- 防止子類繼承
咱們都搞定, 醬紫咱們就完成了一個單例類的建立啦
工程地址: https://github.com/CainRun/DesignPattern/tree/master/SingletonPattern