欢迎访问移动开发之家(rcyd.net),关注移动开发教程。移动开发之家  移动开发问答|  每日更新
页面位置 : > > > 内容正文

objective-c 单例模式详解,

来源: 开发者 投稿于  被查看 5092 次 评论:35

objective-c 单例模式详解,


最近在项目中需要用到单例模式(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建议的方式显然真正的确保了实体的唯一性

相关文章

    暂无相关文章

用户评论