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建議的方式顯然真正的確保了實體的唯一性


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM