2010-05-31 2 views
2

Пожалуйста, смотрите мои комментарии в коде:Есть ли утечка памяти здесь?

-(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; 
} 

ответ

6

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

(см object ownership documentation и 8 squillion очень похожи SO вопросы Это должен быть номер один Objective-C проблема выплывает здесь с большим отрывом.).

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

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

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

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

+2

+1 для ссылки на документы о владении объектами. –

+2

+1 для упоминания предыдущих 8 вопросов. – JeremyP

1

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

  1. «? Почему аварии приложение, когда я пытаюсь и освободить formattedDate я все-таки прошел ссылку на титул собственности»

  2. «Мне нужно, чтобы освободить dateformatter, потому что ... Я не перешли на ссылку "

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

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

0

Слегка связаны между собой, но ...

Initializsers в ObjC должны выглядеть

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

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

Дополнительная информация на ADC: Allocating and Initializing Objects.

Смежные вопросы