這個是多年前寫的了,如今修改了下格式搬到了我們簡書網的平臺,希望大家喜歡。
單例模式是iOS設計模式中常用到的設計模式之一,常用于網絡數據請求,數據庫操作等頻繁調用的模塊,作用呢很簡單,就是節省內存,避免對統一操作進行多次內存開辟而造成不必要的內存浪費。
廢話不多說了,直接上代碼:
新建Singleton類
.h文件
#import <Foundation/Foundation.h>
@interface Singleton : NSObject
+(Singleton *)singleton;
@end
.m文件
#import "Singleton.h"
static Singleton *share = nil;
@implementation Singleton
+(Singleton *)singleton{
@synchronized(self) {
if(share == nil) {
share = [[[self class] alloc] init];
}
}
return share;
}
@end
OK,到此以前的我覺得已經寫完一個單例類了,很多初學者也只是寫到這一步,確實僅憑這些代碼可以完成單例的實現,但是在實際運用過程中他是有缺陷的。
比如在團隊合作過程中,另一個程序猿并不知道這個類是單例類,用alloc init來實現一個對象,那么這個對象就是這個類的普通對象,所以說到這里你應該知道問題所在了吧。
解決上述問題其實也簡單,只需要重寫allocWithZone方法,保證即使有人使用alloc init方法獲取的依舊是已存在的單例(或者第一次創建時走單例方法)。
我們需要修改.m代碼如下:
#import "Singleton.h"
static Singleton *share = nil;
@implementation Singleton
+ (Singleton *)singleton{
@synchronized(self) {
if(share == nil) {
share = [[super allocWithZone:NULL] init];
}
}
return share;
}
+ (instancetype) allocWithZone:(struct _NSZone *)zone{
return [self singleton];
}
@end
OK,這樣就可以確保無論誰怎么使用這個類,最終獲取的都是同一個單例。
細心的初學者朋友可能會對這句話有問題:@synchronized(self),@synchronized的作用是創建一個互斥鎖,防止self對象在同一時間內被其它線程訪問,起到線程的保護作用。
最后再給出一個高大上的方法(GCD實現單例),這算是比較高階的寫法了,只需要對singleton方法進行如下修改:
+ (Singleton*) singleton{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
share = [[super allocWithZone:NULL] init];
});
return share;
}
創造即永恒,喝茶去……