六狼论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

新浪微博账号登陆

只需一步,快速开始

搜索
查看: 104|回复: 0

objective-c 单例模式详解

[复制链接]

升级  9.33%

20

主题

20

主题

20

主题

秀才

Rank: 2

积分
64
 楼主| 发表于 2013-1-4 01:37:08 | 显示全部楼层 |阅读模式
<div id="cnblogs_post_body">最近在项目中需要用到单例模式(singleton),于是对谷歌了一些资料发现objective-c中的单例不是想象中的,apple官方文档建议并非如此,代码量是我好几倍,但是既然官方建议一定是有道理的,谷歌了写资料,多数都是建议这么使用,却没人对此做详解
因为没理解透,用着不踏实,所以决定做些调试,了解透彻!
看完如还有疑问可以进IOS中高级开发群:118623167 和大家交流
按照一般的思路,如下
static MyClass *class = nil;
@implementation MyClass
+(MyClass *)sharedMyClass{
    if (!class) {
        [[self alloc] init];
    }
    returnclass;
}
@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
        }
    }
    returnclass;
}

+(id)allocWithZone:(NSZone *)zone{
    @synchronized(self){
        if (!class) {
            class = [super allocWithZone:zone]; //确保使用同一块内存地址
            return class;
        }
    }
    returnnil;
}

- (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建议的方式显然真正的确保了实体的唯一性
您需要登录后才可以回帖 登录 | 立即注册 新浪微博账号登陆

本版积分规则

快速回复 返回顶部 返回列表