iOS單例設計模式中,我們可以發現,每一個單例的寫法都是相同的,所以我們可以把他們抽取出來,放在一個文件中,當我們要定義一個單例類的時候,就不用再寫重複的代碼了.
下面就教大家用宏定義抽取單例
創建一個.h文件,將相同的代碼用宏定義定義
Singleton.h
// 以後就可以使用interfaceSingleton來替代後面的方法聲明
#define interfaceSingleton(name) +(instancetype)share##name
#if __has_feature(objc_arc)
// ARC
#define implementationSingleton(name) \
+ (instancetype)share##name \
{ \
name *instance = [[self alloc] init]; \
return instance; \
} \
static name *_instance = nil; \
+ (instancetype)allocWithZone:(struct _NSZone *)zone \
{ \
static dispatch_once_t onceToken; \
dispatch_once(&onceToken, ^{ \
_instance = [[super allocWithZone:zone] init]; \
}); \
return _instance; \
} \
- (id)copyWithZone:(NSZone *)zone{ \
return _instance; \
} \
- (id)mutableCopyWithZone:(NSZone *)zone \
{ \
return _instance; \
}
#else
// MRC
#define implementationSingleton(name) \
+ (instancetype)share##name \
{ \
name *instance = [[self alloc] init]; \
return instance; \
} \
static name *_instance = nil; \
+ (instancetype)allocWithZone:(struct _NSZone *)zone \
{ \
static dispatch_once_t onceToken; \
dispatch_once(&onceToken, ^{ \
_instance = [[super allocWithZone:zone] init]; \
}); \
return _instance; \
} \
- (id)copyWithZone:(NSZone *)zone{ \
return _instance; \
} \
- (id)mutableCopyWithZone:(NSZone *)zone \
{ \
return _instance; \
} \
- (oneway void)release \
{ \
} \
- (instancetype)retain \
{ \
return _instance; \
} \
- (NSUInteger)retainCount \
{ \
return MAXFLOAT; \
}
#endif
上面已經將定義單例類的相同代碼,用宏定義抽取出來了,下面就開始使用了
我們創建一個Tools的單例類
Tools.h
#import <Foundation/Foundation.h>
#import "Singleton.h"
@interface Tools : NSObject<NSCopying, NSMutableCopying>
// share + 當前的類名
//+ (instancetype)shareTools;
interfaceSingleton(Tools);
@end
Tools.m
#import "Tools.h"
@implementation Tools
implementationSingleton(Tools)
@end
以後我們定義單例的時候就可以這麼的簡單創建,代碼是不是簡潔多了,下面我們驗證一下
main.m
#import <Foundation/Foundation.h>
#import "Tools.h"
#import "Person.h"
int main(int argc, const char * argv[]) {
Tools *t1 = [[Tools alloc] init]; //內部會調用allocWithZone
Tools *t2 = [Tools new];// [[alloc] init] allocWithZone
Tools *t3 = [Tools shareTools];
Tools *t4 = [t3 copy];
Tools *t5 = [t3 mutableCopy];
NSLog(@"%p, %p, %p, %p, %p", t1, t2, t3, t4, t5);
// 如何判斷當前是ARC還是MRC?
// 可以在編譯的時候判斷當前是否是ARC
#if __has_feature(objc_arc)
NSLog(@"ARC");
#else
NSLog(@"MRC");
#endif
return 0;
}
打印結果: