Проблема управления памятью в Objective-C

Я создал графическое приложение, которое вызывает веб-сервис. Пользователь может масштабировать и перемещаться по графику, и программа время от времени принимает решение вызвать соответствующий веб-сервис для получения дополнительных данных. Это достигается с помощью следующего процесса:

Граф имеет цикл рендеринга, который постоянно рендерит граф, и некоторую логику принятия решений, которая добавляет информацию о вызовах веб-службы в стек.

Отдельный поток берет самую последнюю информацию о вызове веб-службы из стека и использует ее для выполнения вызова веб-службы. Другие объекты в стеке попадают в корзину.

Идея этого состоит в том, чтобы уменьшить количество обращений к веб-службам только до соответствующих и только по одному за раз.

Хорошо, с длинной историей в стороне (за что я извиняюсь), вот моя проблема управления памятью:

На графике есть постоянные (и соответственно заблокированные) объекты 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];
}

2 ответа

Решение

Безопаснее звонить [super dealloc] последний в dealloc, хотя и не обязательно. Возможно, что [super dealloc] выпускает вещи, на которые полагаются другие вещи, такие как KVO.

Почему я должен вызывать super -dealloc последним, а не первым?

Проблема исправлена ​​путём установки [super dealloc]; в конце desctructor. Благодарим Тун Ван Акера.

Из интереса; Кто-нибудь может сказать, применим ли тот же принцип к другим методам, таким как [super init]?

Другие вопросы по тегам