天天看点

宏定义抽取单例

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;
}
           

打印结果:

宏定义抽取单例