单例的初始化在整个app生命周期内(非对象的生命周期)只执行一次,本文介绍通过宏来实现单例方法的定义。代码如下:
----- 单例宏定义 - 头文件 -----
类名 - Singleton.h
// .h文件
#define HMSingletonH(name) + (instancetype)shared##name;
// .m文件
#if __has_feature(objc_arc)
#define HMSingletonM(name) \
static id _instace; \
\
+ (id)allocWithZone:(struct _NSZone *)zone \
{ \
if (_instace == nil) {\
_instace = [super allocWithZone:zone]; \
} \
return _instace; \
} \
\
+ (instancetype)shared##name \
{ \
if (_instace == nil) {\
_instace = [[self alloc]init]; \
} \
return _instace; \
\
} \
\
- (id)copyWithZone:(NSZone *)zone \
{ \
return _instace; \
}
#else
#define HMSingletonM(name) \
static id _instace; \
\
+ (id)allocWithZone:(struct _NSZone *)zone \
{ \
static dispatch_once_t onceToken; \
dispatch_once(&onceToken, ^{ \
_instace = [super allocWithZone:zone]; \
}); \
return _instace; \
} \
\
+ (instancetype)shared##name \
{ \
static dispatch_once_t onceToken; \
dispatch_once(&onceToken, ^{ \
_instace = [[self alloc] init]; \
}); \
return _instace; \
} \
\
- (id)copyWithZone:(NSZone *)zone \
{ \
return _instace; \
} \
\
- (oneway void)release { } \
- (id)retain { return self; } \
- (NSUInteger)retainCount { return 1;} \
- (id)autorelease { return self;}
#endif
----- 需要参加单例的类 -----
类名 - SingletonClass.h
#import <Foundation/Foundation.h>
#import "Singleton.h"
@interface SingletonClass : NSObject
HMSingletonH(SingletonClass)//单例模式
@end
类名 - SingletonClass.m
#import "SingletonClass.h"
@implementation SingletonClass
HMSingletonM(SingletonClass)//单例模式
- (instancetype)init {
if (self = [super init]) {
NSLog(@"单例创建!");
}
return self;
}
@end
----- 创建单例 -----
类名 - ViewController.h
#import <UIKit/UIKit.h>
@interface ViewController : UIViewController
@end
类名 - ViewController.m
#import "ViewController.h"
#import "SingletonClass.h"
@interface ViewController ()
@end
static int i;//计数
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
i = 0;
}
/**
* xib - button action linked
*/
- (IBAction)buttonClick:(UIButton *)sender {
NSLog(@"点击次数:%d",++i);
[SingletonClass sharedSingletonClass];
}
@end
点击button后,打印截图如下:

另附,dispatch_once可用于创建单例,但dispatch_once整个app生命周期内只执行一次,不是对象生命周期内只执行一次;
网友评论