iOS-单例模式

101 阅读2分钟

static修饰变量

  1. 修饰全局变量:全局变量的作用域仅限于当前文件内部(不加的话别人使用extern关键字就能从其他文件访问这个文件的全局变量了)。
  2. 修饰局部变量:能保证局部变量永远只初始化1次,在程序运行过程中,永远只有1分内存。局部变量的生命周期跟全局变量类似,但是不能改变作用域。

一. ARC模式下单例

#pragma mark - GCD模式单例 ARC
 
#import <Foundation/Foundation.h>
 
@interface HMDataTool : NSObject
+ (instancetype)sharedDataTool;
@end
 
#import "HMDataTool.h"
 
@implementation HMDataTool
// 用来保存唯一的单例对象
static id _instace;
 
+ (id)allocWithZone:(struct _NSZone *)zone
{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _instace = [super allocWithZone:zone];
    });
    return _instace;
}
 
+ (instancetype)sharedDataTool
{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _instace = [[self alloc] init];
    });
    return _instace;
}
 
- (id)copyWithZone:(NSZone *)zone
{
    return _instace;
}
@end

二. MRC模式下单例

#pragma mark GCD单例模式 MRC
 
#import "HMDataTool.h"
 
@implementation HMDataTool
// 用来保存唯一的单例对象
static id _instace;
 
+ (id)allocWithZone:(struct _NSZone *)zone
{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _instace = [super allocWithZone:zone];
    });
    return _instace;
}
 
+ (instancetype)sharedDataTool
{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _instace = [[self alloc] init];
    });
    return _instace;
}
 
- (id)copyWithZone:(NSZone *)zone
{
    return _instace;
}

//MRC多了这几个方法
- (oneway void)release{
}
- (id)retain {
    return self;
}
- (NSUInteger)retainCount {
    return 1;
}
- (id)autorelease {
    return self;
}
 
@end

三. 宏实现单例,自定义名称,适配ARC和MRC

#pragma mark - 宏实现单例,自定义名称,适配ARC和MRC

创建一个empty空文件命名HMSingleton.h,在.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 \
{ \
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; \
}
 
#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
  1. /代表下一行是宏
  2. 使用方法: ① 把HMSingleton.h文件导入pch文件,创建单例继承于NSObject。 ② 在需要使用的类的.h文件中加一句HMSingletonH(name),在.m文件中加一句HMSingletonM(name)即可,name是传进去宏的参数名。