
最近在项目中需要用到单例模式(singleton),于是对谷歌了一些资料发现objective-c中的单例不是想象中的,apple官方文档建议并非如此,代码量是我好几倍,但是既然官方建议一定是有道理的,谷歌了写资料,多数都是建议这么使用,却没人对此做详解
因为没理解透,用着不踏实,所以决定做些调试,了解透彻!
看完如还有疑问可以进IOS中高级开发群:118623167 和大家交流
按照一般的思路,如下
static MyClass *class = nil;@implementation MyClass+(MyClass *)sharedMyClass{ if (!class) { class = [[self alloc] init]; } return class;}@end 调试发现
MyClass *A = [[MyClass alloc] init];
NSLog(@"A:%@",A);
MyClass *B = [MyClass sharedMyClass];
NSLog(@"B:%@",B);
打印出的是
A:<MyClass: 0x6c72d30>
B:<MyClass: 0x6a87e60>
不是一个内存地址,也就是不是同一个实体
官方如下方式实现
static MyClass *class = nil;@implementation MyClass+(MyClass *)sharedMyClass{ @synchronized (self){ //为了确保多线程情况下,仍然确保实体的唯一性 if (!class) { [[self alloc] init]; //该方法会调用 allocWithZone } } return class;} +(ID)allocWithZone:(NSZone *)zone{ @synchronized (self){ if (!class) { class = [super allocWithZone:zone]; //确保使用同一块内存地址 return class; } } return nil;}- (ID)copyWithZone:(NSZone *)zone;{ return self; //确保copy对象也是唯一}-(ID)retain{ return self; //确保计数唯一}- (unsigned)retainCount{ return UINT_MAX; //装逼用的,这样打印出来的计数永远为-1}- (ID)autorelease{ return self;//确保计数唯一} - (oneway voID)release{ //重写计数释放方法}@end
再调试
MyClass *A = [[MyClassalloc] init];
NSLog(@"A:%@",A);
MyClass *B = [MyClasssharedMyClass];
NSLog(@"B:%@",B);
MyClass *C = [A copy];
NSLog(@"C:%@",C);
打印出的是
A:<MyClass: 0x6a1e130>
B:<MyClass: 0x6a1e130>
C:<MyClass: 0x6a1e130>
都是指向同一块内存地址
答案已经出来了
apple建议的方式显然真正的确保了实体的唯一性
总结以上是内存溢出为你收集整理的objective-c 单例模式详解全部内容,希望文章能够帮你解决objective-c 单例模式详解所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)