Я создал графическое приложение, которое вызывает веб-сервис. Пользователь может масштабировать и перемещаться по графику, и программа время от времени принимает решение вызвать соответствующий веб-сервис для получения дополнительных данных. Это достигается с помощью следующего процесса:
График имеет цикл рендеринга, который постоянно отображает граф, и некоторую логику принятия решения, которая добавляет информацию о вызовах веб-службы в стек.
Отдельный поток берет самую последнюю информацию о вызове веб-службы из стека и использует ее для выполнения вызова веб-службы. Остальные объекты в стеке сгруппированы.
Идея этого состоит в том, чтобы сократить количество вызовов веб-служб только до тех, которые подходят и только по одному за раз.
Правильно, с длинной историей (за что я извиняюсь), вот моя проблема управления памятью:
На графике есть постоянные (и соответственно заблокированные) объекты NSDate * для текущего отображаемого времени начала и окончания графика. Они передаются в инициализаторы для моих объектов запроса веб-службы. Затем объекты вызова веб-службы сохраняют даты.
После того, как вызовы веб-службы были сделаны (или заблокированы, если они устарели), они выпускают NSDate *.
Сам график высвобождает и перераспределяет новые NSDates * в событии «завершены касания».
Если при вызове removeAllObjects в стеке имеется только один объект вызова веб-службы, EXC_BAD_ACCESS возникает в методе освобождения объекта вызова веб-службы, когда он пытается освободить объекты даты (даже если они кажутся существующими и находятся в области действия в отладчик).
Если, однако, я закомментирую сообщения об освобождении от деструктора, утечка памяти для одного объекта в стеке не происходит, но утечки памяти происходят, если в стеке более одного объекта.
Я понятия не имею, что происходит не так. Не имеет значения, какую символику хранилища я использую для дат объектов вызова веб-службы, так как они назначаются в инициализаторе, а затем только читаются (поэтому для правильности установлены только для чтения).
Похоже, что не имеет значения, если я сохраню или скопирую даты в инициализаторе (хотя все остальное явно выпадает из области видимости или случайно высвобождается в другом месте и вызывает сбой).
Извините, это объяснение слишком длинное, я надеюсь, оно достаточно ясное, но я тоже не боюсь этого. Большое спасибо всем, кто может помочь, даже предложить что-нибудь, что я, возможно, пропустил?
Чтобы немного прояснить ситуацию, вот немного псевдо (ish) кода ... вещи (исключая блокировки и инициализаторы):
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];
}
А затем в объекте вызова веб-службы:
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];
}