// Tools.h #import <Foundation/Foundation.h> @interface Tools : NSObject<NSCopying, NSMutableCopying> // 一般情况下创建一个单例对象都有一个与之对应的类方法,一般情况下用于创建单例对象的方法名称都以share开头, 或者以default开头 + (instancetype)shareInstance; @end
// // Tools.m #import "Tools.h" @implementation Tools + (instancetype)shareInstance { Tools *instance = [[self alloc] init];//调用allocWithZone return instance; } static Tools *_instance = nil; + (instancetype)allocWithZone:(struct _NSZone *)zone //alloc内部会调用allocWithZone { // 由于所有的创建方法都会调用该方法, 所以只需要在该方法中控制当前对象只创建一次即可 /* // 当前代码在多线程中可能会出现问题 NSLog(@"%s", __func__); if (_instance == nil) { NSLog(@"创建了一个对象"); _instance = [[super allocWithZone:zone] init]; //去父类创建,不能用self否则会死循环, } return _instance; */ // 以下代码在多线程中也能保证只执行一次 static dispatch_once_t onceToken;//long类型 dispatch_once(&onceToken, ^{ _instance = [[super allocWithZone:zone] init]; }); return _instance; } // copyWithZone方法用什么调用? 对象,对象已经有了,就用原来的对象。 - (id)copyWithZone:(NSZone *)zone{ // Tools *t = [[[self class] allocWithZone:zone] init]; //调用allocWithZone,所以这里也是单利, // return t; return _instance; } - (id)mutableCopyWithZone:(NSZone *)zone { // Tools *t = [[[self class] allocWithZone:zone] init]; // return t; return _instance; } //MRC:MRC才可以写release,retain,retainCount - (oneway void)release { // 为保证整个程序过程中只有一份实例, 在这个方法中什么都不做,单利释放了就没有了。 } - (instancetype)retain { return _instance; } - (NSUInteger)retainCount { // return 1; // 注意: 为了方便程序员之前沟通, 一般情况下不会在单例中返回retainCount = 1 // 而是返回一个比较大得值 return MAXFLOAT; } @end
// // main.m // 单例:只有一个实例,只有程序挂掉实例才释放。 // #import <Foundation/Foundation.h> #import "Tools.h" int main(int argc, const char * argv[]) { //ARC // 单例就是无论怎么创建都只能有一个实例对象 // 如果地址相同就代表着是同一个实例对象 Tools *t11 = [[Tools alloc] init]; //alloc内部会调用allocWithZone,这里调用allocWithZone, Tools *t21 = [Tools new];// [[alloc] init], allocWithZone,,这里调用allocWithZone, Tools *t31 = [Tools shareInstance];//先调用shareInstance再调用allocWithZone, Tools *t41 = [t31 copy]; Tools *t51 = [t31 mutableCopy]; NSLog(@"%p, %p, %p, %p, %p", t11, t21, t31, t41, t51);//0x1005035e0, 0x1005035e0, 0x1005035e0, 0x1005035e0, 0x1005035e0 //MRC Tools *t2 = [[Tools alloc] init]; [t2 retain]; [t2 retain]; [t2 retain]; [t2 retain]; [t2 retain]; NSLog(@"retainCount = %lu", [t2 retainCount]);//4299163232 NSLog(@"t2 = %p", t2);//t2 = 0x1005035e0 [t2 release]; Tools *t1 = [Tools shareInstance]; NSLog(@"retainCount = %lu", [t1 retainCount]);//4299163232 NSLog(@"t1 = %p", t1);//0x1005035e0 [t1 release]; return 0; }
本文转自农夫山泉别墅博客园博客,原文链接:http://www.cnblogs.com/yaowen/p/7443685.html,如需转载请自行联系原作者