我創建了一個調用Web服務的圖形應用程序。用戶可以放大圖形的移動範圍,程序偶爾會決定調用Web服務以獲取更多數據。這是通過以下過程實現的:Objective-C內存管理問題
該圖具有呈現循環,該循環不斷呈現圖形,以及將Web服務調用信息添加到堆棧的一些決策邏輯。
單獨的線程從堆棧中獲取最新的Web服務調用信息,並使用它來進行Web服務調用。堆棧中的其他對象被分類。
這樣做的想法是將Web服務調用的數量減少到僅適用的那些,並且一次只有一個。
權,與長故事的方式進行(對此我表示歉意),這裏是我的內存管理問題:
有圖有持續性(和適當鎖定)的NSDate *當前顯示的對象開始&圖表的結束時間。這些傳遞給我的Web服務請求對象的初始化程序。 Web服務調用對象然後保留日期。
Web服務調用完成後(或者如果它們已過期,則爲binned),它們釋放NSDate *。
該圖本身在「觸摸已結束」事件中釋放並重新分配新的NSDates *。
如果在調用removeAllObjects時堆棧上只有一個Web服務調用對象,則在Web服務調用對象的釋放方法嘗試釋放日期對象時發生EXC_BAD_ACCESS(即使它們看起來存在且處於作用域中在調試器中)。
但是,如果我從析構函數註釋掉釋放消息,則釋放堆棧上的一個對象時不會發生內存泄漏,但如果堆棧中有多個對象,則會發生內存泄漏。
我完全不知道怎麼回事。它沒有什麼區別我用於Web服務調用對象的存儲語義,因爲它們是在初始化程序中分配的,然後才被讀取(所以爲了正確性而設置爲只讀)。
如果我在初始化程序中保留或複製日期(儘管其他任何明顯超出範圍或在別處釋放並導致崩潰),似乎也沒有什麼區別。
對不起,這個解釋很長,我希望它已經足夠清晰,但我不是在賭博,或者我害怕。非常感謝任何能提供幫助的人,甚至提出我可能錯過的任何事情?
要明確希望事情了一下,這裏是一些僞(ISH)代碼...東西(不包括鎖和initialisers):
NSMutableArray* requests;
NSDate* start, end;
-(void)webServiceThread
{
if([requests count] > 1)
{
[self doRequestWithParams:[requests lastObject]];
[requests removeAllObjects];
}
}
-(void)render
{
if(conditions for another web service call are met)
{
WebServiceRequest* new = [[WebServiceRequest alloc] initWithDates:start :end];
[requests addObject:new];
[new release];
}
[self doRendering];
}
-(void)touchesEnded
{
[start release];
[end release];
start = [[NSDate dateSinceTimeInterval:chartLeft] retain]; //Ficticious NSDate Method names for example.
end = [[NSDate dateSinceTimeInterval:chartRight] retain];
}
然後在Web服務調用對象:
NSDate* startDate;
NSDate* endDate;
-(void)initWithDates:start :end
{
startDate = [start retain];
endDate = [end retain];
}
-(void)dealloc
{
[super dealloc];
//The following two lines cause EXC_BAD_ACCESS if this is the only object on the request stack. If they are commented, however, memory is leaked if this is not the only object on the request stack.
[startDate release];
[endDate release];
}
這聽起來像是有一個釋放到很多。從你的解釋來看,這聽起來像是這個額外釋放發生的地方並不明顯。我想在某種程度上autorelease必須偷偷溜進去,你錯過了。如果您可以發佈相關代碼 - 所有作業,保留和發佈日期,這將有所幫助。 – 2010-04-22 13:49:57
作爲一個小提示,儘管不需要,在'dealloc'中最後調用'[super dealloc]'最後通常更安全。 http://stackoverflow.com/questions/909856/why-do-i-have-to-call-super-dealloc-last-and-not-first – 2010-04-22 13:58:44
感謝您的回覆,已添加僞代碼(實際代碼是大量的更長;也可能是問題的一部分)。自動釋放的想法沒有發生在我身上,但是在適用的情況下,所有東西都有一個存儲方法(目前保留)。 – Tobster 2010-04-22 13:58:58