Проблема управления памятью в Objective-C - PullRequest
0 голосов
/ 22 апреля 2010

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

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

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

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

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

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

0 голосов
/ 22 апреля 2010

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

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

0 голосов
/ 22 апреля 2010

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...