2011-01-27 2 views
0

Я только что запустил приложение через «Утечки в инструментах», и мне сказали, что следующий код вызывает утечки, но я не понимаю, как это сделать.Происходит ли этот код?

Я выделить несколько NSMutableArray с в моем viewDidLoad с этим кодом:

- (void)viewDidLoad { 
    [super viewDidLoad]; 
    self.currentCars = [[NSMutableArray alloc] init]; 
    self.expiredCars = [[NSMutableArray alloc] init]; 
} 

Затем я заполнить эти массивы внутри моего viewWillAppear метода со следующим:

[self.currentCars removeAllObjects]; 
[self.expiredCars removeAllObjects]; 
for (Car *car in [self.dealership cars]) { 
    if ([car isCurrent]) 
     [self.currentCars addObject:car]; 

    if ([car isExpired]) 
     [self.expiredCars addObject:car]; 
} 

А позже в коде отпустите эти массивы здесь:

- (void) viewWillDisappear:(BOOL)animated { 

    if (currentCars != nil) { 
     [currentCars release], currentCars = nil; 
    } 
    if (expiredCars != nil) { 
     [expiredCars release], expiredCars = nil; 
    } 

    [super viewWillDisappear:animated]; 
} 

Любые идеи? Благодаря!

+0

Я не вижу утечек. Должно быть в другом месте, не могли бы вы добавить какой-то связанный код? – BoltClock

+2

Невозможно сказать, основываясь исключительно на этом образце. –

+0

Возможно, я смотрю на неправильное место в Инструментах, но он поднимает линию '[self.currentCars addObject: car];' и помещает индикатор со 100% на эту строку ... Я просто читаю это неправильно? –

ответ

2

Ваша утечка здесь:

self.currentCars = [[NSMutableArray alloc] init]; 
self.expiredCars = [[NSMutableArray alloc] init]; 

Предполагая, что вы объявили собственности accessores, как это:

@property(nonatomic, retain) NSMutableArray *currentCars; 
@property(nonatomic, retain) NSMutableArray *expiredCars; 

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

Если вы должны были сделать это, например, с currentCars, вы легко найдете свою утечку. Вот что происходит:

self.currentCars = [[NSMutableArray alloc] init]; 
// The 'init' makes the retain count 1. 

// 'self.currentCars = ..' translates to the setCurrentCars: method. 
// You probably did not implement that method yourself, 
// but by synthesizing your property it is automatically implemented like this: 
- (void)setCurrentCars:(NSMutableArray *)array { 
    [array retain]; // Makes the retain count 2 
    [currentCars release]; 
    currentCars = array; 
} 

// In your viewWillDisappear: method 
[currentCars release], currentCars = nil; // Makes the retain count 1 so the object is leaked. 

Решение прост. Используйте это:

NSMutableArray *tempMutableArray = [[NSMutableArray alloc] init]; 
self.currentCars = tempMutableArray; 
[tempMutableArray release]; 

Немного прохода. Вы не должны отпускать свои объекты в viewWillDisappear:. Рекомендуемое место для этого - dealloc. Таким образом, ваш код будет:

- (void)dealloc { 
    [currentCars release], currentCars = nil; 
    [expiredCars release], expiredCars = nil; 
    [super dealloc]; 
} 
+0

Звонки на '-init' не меняют количество учетных записей. Счет сохранения равен 1 (по крайней мере, насколько нам известно) по вызову '-alloc', хотя Apple советует думать с точки зрения владения, а не удерживать счета, так как попытка рассчитать количество накоплений зависит от предположений, которые не будут всегда оказываются правильными. – jlehr

+0

Кроме того, не обязательно ошибочно снимать объекты в '-viewWillDisappear:', чтобы уменьшить потребление памяти, если переменные базового экземпляра установлены на 'nil', как это сделал OP. С другой стороны, установка переменных экземпляра в 'nil' в' -dealloc' вряд ли будет полезна. – jlehr

0

Если вы делаете что-то очень странное в currentCars, expiredCars, dealership или cars, нет, нет никакой утечки там.

Указатель приборов на место утечки не обязательно там, где объект фактически протекает сам по себе. Если бы я догадался, я бы сказал, что вы, вероятно, пренебрегаете выпуском currentCars или expiredCars в своем методе dealloc.

+0

Да, мне интересно, будет ли вызвано viewWillDisappear. –

2

Проблема (вероятно) в том, что вы используете средства доступа к свойствам для начальной настройки массивов в -viewDidLoad. Так как хорошо реализованные аксессоры свойств сохранят объект, вы получаете 1 удержание из + alloc, а другое - от его назначения. Чтобы исправить это, вы должны освободить свои массивы после их назначения или использовать [NSMutableArray array], чтобы получить автореализованный, который будет использоваться для ваших первоначальных назначений.

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