Управление памятью Objective-C: сбой при выпуске - PullRequest
0 голосов
/ 14 августа 2011

Я новичок в Objective-C и, похоже, не могу правильно понять код управления памятью.У меня есть следующий код:

Media* myMedia = [self.myMediaManager getNextMedia];

self.navigationItem.title = [self.myMediaManager getCategory];
[self.btnImage setImage:myMedia.imageFile forState: UIControlStateNormal];
[self.lblImage setText:myMedia.imageLabel];

//[myMedia release];

Мое приложение падает, если я раскомментирую вышеприведенную строку.Нужно ли делать что-то особенное, когда я создаю экземпляр myMedia?

EDIT:

Если myMediaManager должен выпустить его, когда он это сделает?Вот мой код для getNextMedia:

- (Media*) getNextMedia {

    DLog(@"Start");

    Media* nextMedia = [[Media alloc] init];

    [self setNextMediaIndex];

    if (self.mediaIndex > -1)
    {
        nextMedia = [mediaArray objectAtIndex: self.mediaIndex];
    }

    return nextMedia;
}

EDIT2: я исправил проблему сбоя (я выпускал объект, который мне не принадлежал).Я все еще вижу утечки и не могу понять, в чем проблема.

Ответы [ 5 ]

4 голосов
/ 14 августа 2011

Только объекты, которыми вы владеете , могут быть освобождены.

Вы можете release объектов, если вы new, alloc, copy, mutableCopy или retain сначала их.

Так как в [self.myMediaManager getNextMedia]; нет выделения / копирования / сохранения, вы не можете его освободить.

4 голосов
/ 14 августа 2011

Поскольку myMedia здесь не сохраняется, вам не нужно его выпускать.Когда источник (self.myMediaManager) освобождает его, он немедленно уничтожается.

NSString *string = [[NSString alloc] init];
[string release]; // now we have to release the string, since we allocated it.

NSString *string = self.navigationItem.title;
// now we don't, since it's a property of `navigationItem` and we didn't retain it.
1 голос
/ 14 августа 2011

Этот обновленный код является подозрительным:

Media* nextMedia = [[Media alloc] init];

[self setNextMediaIndex];

if (self.mediaIndex > -1)
{
    nextMedia = [mediaArray objectAtIndex: self.mediaIndex];
}

В зависимости от условия в предложении if(), вы назначаете новое значение для nextMedia , что делает значение, которое вы только что присвоилинедоступен, т. е. не может быть освобожден.

Кроме того, вы не сохраняете значение, полученное из массива, поэтому также не следует освобождать его.Но если предложение if() не выполняется, у вас все еще есть выделенный вами экземпляр, и его следует освободить.

Это не хорошо.Попробуйте:

Media* nextMedia = [[Media alloc] init];
[self setNextMediaIndex];
if (self.mediaIndex > -1)
{
    [nextMedia release];
    nextMedia = [[mediaArray objectAtIndex: self.mediaIndex] retain];
}

Вы также можете сделать (и я бы предпочел):

Media *nextMedia;
[self setNextMediaIndex];
if (self.mediaIndex > -1)
{
    nextMedia = [[mediaArray objectAtIndex: self.mediaIndex] retain];
}
else
{
    nextMedia = [[Media alloc] init];
}

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

1 голос
/ 14 августа 2011

Общее правило для управления памятью следующее:

Для каждого retain, alloc, copy или new вам необходимо позвонить release или autorelease.

Поскольку вы не вызывали их, вам не нужно выпускать myMedia.

Для получения дополнительной информации взгляните на этот другой ответ, который я опубликовал , который касается темы. Кроме того, поскольку вы новичок в разработке для iOS, я предлагаю также посмотреть этот ответ .

1 голос
/ 14 августа 2011

На данный момент, поскольку вы только учитесь, вам, вероятно, стоит начать использовать ARC с бета-версиями iOS5 для XCode. Хорошо иметь понимание, но использование ARC избавит вас от многих потенциальных ловушек - к тому времени, когда вы научитесь достаточно производить что-то, iOS5 выйдет. Вы по-прежнему можете создавать приложения для iOS4, поэтому вы по-прежнему сможете охватить множество людей.

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