signal(单例)

~ 写在正文之前:文章转移到翻这个墙中,希望继续关注啦。(2017.11.5)

signal(单例)

  • 1.1 概念

(1)单例模式

(1.1)在程序运行过程,一个类只有一个实例,而且该实例易于供外界访问
(1.2)方便地控制了实例个数,并节约系统资源
(1.3)单例是不可以用继承的,因为不能父类与子类共用一个全局变量

(2)使用场合

在整个应用程序中,共享一份资源(这份资源只需要创建初始化1次)
  • 1.2 实现通过单例(在ARC与MRC中均可执行)

(1)实现步骤

01 在类的内部提供一个static修饰的全局变量
02 重写+allocWithZone方法,保证永远都只为单例对象分配一次内存空间
03 提供一个类方法,方便外界访问
04 严谨起见,重写-copyWithZone方法和-MutableCopyWithZone方法
05 通过条件编译判断是否是ARC{__has_feature(objc_arc)},若是,则不再执行代码,否则执行下述06-09代码
06 重写release方法
07 重写retain方法
08 建议在retainCount方法中返回一个最大值
09 结束条件编译

(2)如果在MRC中运行,需配置MRC环境知识

01 注意ARC不是垃圾回收机制,是编译器特性
02 配置MRC环境:build setting ->搜索automatic ref->修改为NO

(3)相关代码

//提供一个static修饰的全局变量,强引用着已经实例化的单例对象实例
static id _instance;

//保证永远只分配一次存储空间
+(instancetype)allocWithZone:(struct _NSZone *)zone
{
    //使用GCD中的一次性代码
//    static dispatch_once_t onceToken;
//    dispatch_once(&onceToken, ^{
//        _instance = [[super allocWithZone:zone]init];
//    });

    //使用加锁的方式,保证只分配一次存储空间
    @synchronized(self) {
        if (_instance == nil) {
            _instance = [super allocWithZone:zone];
        }
    }
    return _instance;
}

//类方法,返回一个单例对象
+(instancetype)shareTools
{
     //注意:这里建议使用self,而不是直接使用类名Tools(考虑继承)

    return [[self alloc]init];
}

//让代码更加的严谨
-(nonnull id)copyWithZone:(nullable NSZone *)zone
{
//    return [[self class] allocWithZone:zone];
    return _instance;
}

-(nonnull id)mutableCopyWithZone:(nullable NSZone *)zone
{
    return _instance;
}

#if __has_feature(objc_arc)
    //如果是ARC环境下
#else
    //如果是MRC环境下
//在MRC环境下,如果用户retain了一次,那么直接返回instance变量,不对引用计数器+1
//如果用户release了一次,那么什么都不做,因为单例模式在整个程序运行过程中都拥有且只有一份,程序退出之后被释放,所以不需要对引用计数器操作
-(oneway void)release
{
}

-(instancetype)retain
{
    return _instance;
}

//惯用法,有经验的程序员通过打印retainCount这个值可以猜到这是一个单例
-(NSUInteger)retainCount
{
    return MAXFLOAT;
}
#endif

单例封装宏

01 注意条件编译的代码不能包含在宏定义里面
02 宏定义的代码只需要写一次就好,之后直接拖到项目中用就OK
    #define SingleH(name) +(instancetype)share##name;

    #if __has_feature(objc_arc)
//ARC
#define SingleM(name) static id _instance;\
+(instancetype)allocWithZone:(struct _NSZone *)zone\
{\
    static dispatch_once_t onceToken;\
    dispatch_once(&onceToken, ^{\
        _instance = [super allocWithZone:zone];\
    });\
    return _instance;\
}\
\
+(instancetype)share##name\
{\
    return [[self alloc]init];\
}\
\
-(id)copyWithZone:(NSZone *)zone\
{\
    return _instance;\
}\
\
-(id)mutableCopyWithZone:(NSZone *)zone\
{\
    return _instance;\
}

#else
//mrc
#define SingleM(name) static id _instance;\
+(instancetype)allocWithZone:(struct _NSZone *)zone\
{\
static dispatch_once_t onceToken;\
dispatch_once(&onceToken, ^{\
_instance = [super allocWithZone:zone];\
});\
return _instance;\
}\
\
+(instancetype)share##name\
{\
return [[self alloc]init];\
}\
\
-(id)copyWithZone:(NSZone *)zone\
{\
return _instance;\
}\
\
-(id)mutableCopyWithZone:(NSZone *)zone\
{\
return _instance;\
}\
-(oneway void)release\
{\
}\
\
-(instancetype)retain\
{\
    return _instance;\
}\
\
-(NSUInteger)retainCount\
{\
    return MAXFLOAT;\
}

#endif
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容