2011-02-04 22 views
2

我一直在使用使用一個NSMutableData實例的字節,而允許它被自動釋放

NSMutableData* mutableData = [NSMutableData dataWithLength: someLength]; 
void* bitmapData = [mutableData mutableBytes]; 
CGContextRef context = CGBitmapContextCreate(bitmapData,...); 
// ...use context 
CGContextRelease(context); 

我有一個自動釋放池的地方,但是看着這儀器時,mutableData似乎不被釋放。
我想過使用下面的alloc/init,但我不確定發送release是否會清除bitmapData

NSMutableData* mutableData = [[NSMutableData alloc] initWithLength: someLength]; 
void* bitmapData = [mutableData mutableBytes]; 
[mutableData release]; 
//... 

在這裏使用NSMutableData的正確方法是什麼?

我認爲使用NSMutableData而不是malloc()free()會很方便,因爲它會自動發佈。但現在我不確定這是否屬實。

回答

1

當你說mutableData似乎沒有被釋放,你的意思是在CGContextRelease()點,或者你的意思是它永遠不會釋放,每次你運行它泄漏?

在第一個示例中,因爲您使用了-dataWithLength:,所以您不會指望mutableData將釋放,直到autorelease池消耗(通常在事件循環結束時)。在你的第二個例子中,是否會釋放mutableData還未定義。對-mutableBytes的調用可能會應用一個保留和autorelease以確保該指針對於其餘事件循環是有效的(這在這些類型的方法中很常見),但文檔沒有說,所以第二個示例是未定義的行爲如果您以後使用bitmapData

現在,如果mutableData泄漏,那麼你很可能過度保留在其他地方。

+0

是的,即使在CGContextRelease()之後它也不會釋放。我不會將原始數據或NSMutableData傳遞給上下文創建函數。 – eugene 2011-02-04 15:12:26

0

爲其mutableBytes詢問一個NSMutableData的實例只是返回一個指向它爲您管理的現有(已分配)緩衝區的指針。從管理的角度來看,它對內存沒有任何影響。

因此,在您的第一個示例中,當在Instruments中查看mutableData時,似乎並未取消分配這一事實,這可能與當時的autorelease池環境有關。以這種方式使用mutableData的代碼是否有NSAutoreleasePool?你看到控制檯中的警告:「autorelease調用沒有游泳池,只是漏水」?如果是這樣,你只需要包裝的代碼:

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 
// bitmap drawing code here 
[pool drain]; 

在第二個示例,你可以在NSMutableData實例中使用分配/ init,但是你需要釋放你使用指針,你做了之後從mutableBytes獲得。調用release後指針將指向釋放(釋放)的內存,訪問它將導致令人生畏的EXC_BAD_ACCESS。

此外,使用malloc/free可能是我的第一選擇,因爲您明確瞭解如何以及何時分配和釋放內存。 NSMutableData + autorelease實際上並不會真正爲你購買任何東西,除非有一些開銷,如果你不用其他東西來使用它。

相關問題