This method is of no value in debugging memory management issues. Because any number of framework objects may have retained an object in order to hold references to it, while at the same time autorelease pools may be holding any number of deferred releases on an object, it is very unlikely that you can get useful information from this method.
官網(wǎng)明確表示,不要拿retainCount去調(diào)試內(nèi)存管理方面的問題,因為有自動釋放池等存在逞泄,導(dǎo)致retainCount的值并不準(zhǔn)確烦周。
PS:ARC模式下是不允許調(diào)用retainCount的帚稠,可以把ARC文件轉(zhuǎn)為MRC,在targets的build phases選項下Compile Sources下選擇要不使用ARC編譯的文件孵运,輸入-fno-objc-arc穆律;MRC轉(zhuǎn)ARC惠呼,輸入-fobjc-arc即可
以下以一個簡單的例子來說明:
-(void)test
{
NSString * str1 = [NSString stringWithFormat:@"abcdef"];
NSString * str2 = [NSString stringWithString:str1];
NSString * str3 = str1;
NSLog(@"str1:%lu,%d",(unsigned long)[str1 retainCount],[str1 retainCount]);
NSLog(@"str2:%lu,%d",(unsigned long)[str2 retainCount],[str2 retainCount]);
NSLog(@"str3:%lu,%d",(unsigned long)[str3 retainCount],[str3 retainCount]);
NSLog(@"str1地址:%p,str2地址%p",str1,str2);
NSLog(@"unsigned long:%lu",ULONG_MAX);
}
可能會以為str1,str2峦耘,str3的引用計數(shù)為1剔蹋?
下面為輸出結(jié)果:
2017-07-06 10:45:26.187 PoolTest[89591:2057536] str1:18446744073709551615,-1
2017-07-06 10:45:26.188 PoolTest[89591:2057536] str2:1,1
2017-07-06 10:45:26.188 PoolTest[89591:2057536] str3:18446744073709551615,-1
2017-07-06 10:45:26.188 PoolTest[89591:2057536] str1地址:0xa006665646362616,str2地址0x600000057ac0
2017-07-06 10:45:26.188 PoolTest[89591:2057536] unsigned long:18446744073709551615
正如官網(wǎng)所提到的,不要指望retainCount能給出正確的內(nèi)存管理辅髓,stringWithFormat是內(nèi)部使用了autorelease泣崩,而且還有自動釋放池持有當(dāng)前對象,所以也不能保證str1能像我們期望的那樣輸出1利朵。
str2是調(diào)用NSString的stringWithString? Copy創(chuàng)建了一個新的對象,可以從輸出結(jié)果的str1和str2的地址看出猎莲,stringWithString的官網(wǎng)也解釋很清楚:
Returns a string created by copying the characters from another given string.
str3是直接賦值str1绍弟,所以引用計數(shù)跟str1一樣不準(zhǔn)確,有符號的情況下輸出-1著洼,無符號的情況下輸出unsigned long 的最大值:18446744073709551615樟遣。
所以而叼,不要指望retainCount給你太多準(zhǔn)確有價值的信息,有時候?qū)ο笫菦]被任何對象持有豹悬,我們期望是retainCount為0葵陵,但是這不是絕對的,還有自動釋放池等等很多制約影響著瞻佛,內(nèi)存管理沒有我們表象或者猜想中看著那么簡單脱篙,所以retainCount是不一定準(zhǔn)確的。只要對象遵循內(nèi)存管理策略伤柄,我們可以利用Instruments工具等去診斷內(nèi)存管理問題绊困。