Здесь есть утечка памяти? - PullRequest
2 голосов
/ 31 мая 2010

Пожалуйста, смотрите мои комментарии в коде:

-(id)initWithCoordinate:(CLLocationCoordinate2D)c title:(NSString *)t
{        
    [super init];
    coordinate = c;
    NSDate *today = [NSDate date];

    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    [dateFormatter setDateStyle:NSDateFormatterLongStyle];

    NSString* formattedDate = [NSString stringWithFormat:@"%@ %@",
                           [dateFormatter stringFromDate:today], t];


    [self setTitle:formattedDate]; //Why does the app crash when I try and release formattedDate?  I have after all passed its reference to the title property?


    [dateFormatter release]; //I need to release the dateformatter because I have finished using it and I have not passed on a reference to it

    return self;
}

Ответы [ 3 ]

6 голосов
/ 31 мая 2010

Нет, выглядит хорошо. stringWithFormat возвращает автоматически выпущенный объект - вы не владеете им, если у вас нет retain этого, чего у вас нет, поэтому вы не должны освобождать его. Вы выделили dateFormatter самостоятельно, поэтому действительно владеете им и должны release.

(См. документацию по владению объектами и 8 с половиной миллиардов очень похожих вопросов SO. Это должно быть задачей номер один с, которая возникает здесь со значительным отрывом.)

Редактировать: На самом деле, глядя на ваш комментарий, здесь есть очень незначительная более тонкая проблема, хотя результат такой же (и фактически подчеркивает точку зрения о собственности).

Когда вы передаете строку в setTitle, она может retain сама строка, и в этом случае вызов release может не вызвать немедленного сбоя. Тем не менее, вы все равно будете переиздавать, и в конце концов это вас укусит. Просто было бы труднее найти причину проблемы дальше по линии.

Как это происходит, setTitle делает копию, а не сохраняет свою. Это довольно часто встречается с NSString свойствами. Одна из причин заключается в том, что вы можете вместо этого передать NSMutableString, а затем случайно изменить его в более поздний момент, который может испортить приемник. Принимать личную копию безопаснее. В качестве бонуса он сразу же выставляет вам чрезмерный выпуск и позволяет легко его исправить.

В любом случае, точка стоит: только когда-либо release что-то, что вы знаете, у вас есть. Если вы только что передали его какому-то другому объекту, то ответственность за этот объект лежит на том, владеет ли он им, а не вашим.

1 голос
/ 01 июня 2010

Похоже, у вас есть некоторые радикальные заблуждения о том, как сохранять и отпускать работу. Вы говорите:

  1. "Почему происходит сбой приложения, когда я пытаюсь выпустить formattedDate? Я все-таки передал его ссылку на свойство title"

  2. «Мне нужно выпустить форматирование даты, потому что… я не передал ссылку на него» * ​​1009 *

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

В двух словах: вы владеете объектом и несете ответственность за его освобождение, если вы получили его по методу new alloc или copy или если вы retain его редактировали. В случае NSDateFormatter вы получили его от alloc, поэтому вы должны его освободить. В случае строки, ни одна из этих вещей не является истинной, поэтому вы должны , а не освободить этот объект, который вам не принадлежит.

0 голосов
/ 01 июня 2010

Немного не связано, но ...

Инициализаторы в ObjC должны выглядеть как

- (id)init;
{
    self = [super init];
    if (self == nil)
        return self;
    ...
    return self;
}

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

Больше информации на АЦП: Распределение и инициализация объектов .

...