2011-05-09 101 views
0

我想知道CALayer類和它的引用計數器的行爲。請看下面的兩段代碼:關於保留和釋放問題的困惑

第一:

CALayer *layer = [[CALayer alloc] init]; 
NSLog(@"retain count: %d", [layer retainCount]); // log: retain count: 1 
[layer release]; // no problem so far 

[layer release]; // this leads to a crash as expected 

二:

CALayer *layer = [[CALayer alloc] init]; 

NSLog(@"retain count: %d", [layer retainCount]); // log: retain count: 1 
layer.opaque = YES; //increases the retain count, WHY?!? 
NSLog(@"retain count: %d", [layer retainCount]); // log: retain count: 2 

[layer release]; // no problem so far 

[layer release]; // this leads NOT to a crash as expected 

在第一個片段,因爲我希望它也崩潰(殭屍一切時... )在第二個釋放消息。

在第二個,意想不到的事情發生。在初始化後調用任何消息(例如,layer.opaque = YES)會將保留計數器增加1,但只會增加消息的第一個調用。所以保留計數器總是從1到高。爲了證明這不僅僅是一個數字問題,我使用了第二個版本。第二次發佈後,圖層只能從內存中釋放。

這種行爲也可以用autorelease產生。

那麼,爲什麼向該圖層的消息會增加其保留計數?我錯過了關於保留和發佈問題的一些信息嗎?

在此先感謝

馬爾科

回答

1

你錯過了關於不使用保留調試計數的部分。不要這樣做。對象的保留數量與您的業務無關。

專注於您對物體的所有權。如果您擁有它(保留,分配,複製或新建),則必須發佈一次。

如果在您完成保留/釋放循環之後,某個對象仍然存在,那意味着其他東西擁有它並負責釋放它。如果你再次釋放它,你已經打破了所有權,只能悲慘地結束。

因此,如果layer.opaque = YES增加保留計數,讓它。不要擔心。你已經履行了你的義務,做任何事情都會使保留/釋放週期在別的地方失衡。

+0

感謝您的回答,但如果我忽略了這一點,我的應用程序會溢出內存。所以我必須查看哪些內存未被釋放。我追查到這個問題。如果我釋放所有CALayer兩次,一切正常。即使是我的帖子中的第二個片段在單獨測試時也能正常工作(不生成殭屍)。這個(鬼)保留只在CALayer中產生。 – marlu 2011-05-09 07:22:10

1

retainCount沒用。別叫它。

那麼,爲什麼消息到層 增加其保留數?我有沒有錯過 一些Infromation約保留和 發行問題?

因爲它是框架的內部實現細節。

如果你平衡你的保留和釋放,那麼你的對象將被正確釋放。

如果一個對象時間太長(足以導致應用程序崩潰),這是因爲您的代碼沒有正確清理。在圖層的情況下,最常見的原因是在您的應用完成後,未能從圖層/視圖層次結構中移除圖層。