2014-09-19 28 views
0

我只是問一個合乎邏輯的問題。如果我先釋放池然後釋放該對象,會從內存釋放對象嗎?例如,這裏是我的代碼片段:如果我釋放對象,釋放對象所屬的池後會發生什麼情況?


[self performSelectorInBackground:@selector(setImage) withObject:nil]; 

-(void)setImage 
{ 
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init]; 

    NSString *strUrl = @"--some URL--"; 

    NSData *imageData = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:strUrl]]; 
    UIImage *myimage = [[UIImage alloc] initWithData:imageData]; 

    [pool release]; 
    [imageData release]; 
} 

假設代碼段非ARC環境下執行。

回答

1

這樣可以,因爲您從未將imageData對象添加到autorelease池,因此池不會釋放它。如果您已經添加爲imageData對象的自動釋放池是這樣的:

[[[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:strUrl]] autorelease]; 

額外的釋放將是一個overrelease和您的應用程序可能會崩潰。 它看起來像你泄漏myImage,因爲這是從來沒有釋放。

+0

如果我在我的代碼片段中使用autorelease,它將如何被過度釋放?因爲,池負責發送發佈消息。但是,在我的情況下,我在池釋放後釋放對象。如果我理解錯誤,請糾正我。 – NSPratik 2014-09-19 11:00:00

+1

如果您將'autorelease'添加到'imageData',那麼當您創建它時,它將具有1的保留計數,當autorelease池釋放'imageData'時,保留計數將遞減,並且將被處理。如果你嘗試釋放'imageData',你將會崩潰。如果你添加'autorelease'到'myImage',它會正常工作。 – 2014-09-19 11:03:30

+0

好的,所以當執行到_ [imageData release] _時,imageData對象將不會被找到並導致崩潰。 – NSPratik 2014-09-19 11:08:05

1

當你調用[pool release];立即解除分配不會發生在添加到池的autorelease對象上。因此,當您明確調用release時,imageData的引用計數將減少1.當池釋放任一應用程序會因釋放實例而崩潰或消息發送給nil對象。