2012-06-14 2 views
0

Я проверяю keepCount для подсмотра после добавления в представление. код:Addsubview и dealloc для утечек памяти (retainCount)

- (void) loadView{ 
    //... 
    toolbar = [[UIToolbar alloc] initWithFrame:nil]; 
    [[self view] addSubView:toolbar]; 
} 

- (void) dealloc{ 
    NSLog(@"count=%d", [toolbar retainCount]); // count=2 
    [toolbar removeFromSuperView]; 
    NSLog(@"count=%d", [toolbar retainCount]); // count=1 
    [toolbar release] 
    NSLog(@"count=%d", [toolbar retainCount]); // count=1 
    toolbar = nil; 
    NSLog(@"count=%d", [toolbar retainCount]); // count=0 
} 

Из этого кода в dealloc {}, у меня есть несколько вопросов:

1, первый журнал retainCount на панели инструментов 2, поскольку панель инструментов после инициализации и добавил к себе зрения, retaincount будет до 2.

2, После того, как панели инструментов removeFromSuperView, то retainCount станет равным 1.

3, После того, как панель инструментов вызвать метод освобождения, retainCount еще один, он не может станет 0. В моих вариантах, потому что супер просмотр остается панель инструментов (самоопределение не выпускается), поэтому панель инструментов не может перезагрузиться до 0.

4, Если вызов панели инструментов установлен на нуль, значение keepCount будет равно 0. Этот журнал бесполезен.

Мои вопросы:

а) на панели инструментов вызовите removeFromSuperView и релиз API, результат тот же, панель инструментов retainCount только станет равным 1. Таким образом, если я проверить код использовать только каждый из них , результат будет таким же. Итак, могу ли я заключить, что пользователь может только назвать каждый API в порядке?

b) Из документа яблока подъярус добавляется в представление о себе, само представление остается дескриптором панели инструментов, поэтому в методе dealloc, если viewDidUnload не вызывается, панель keepCount не может быть уменьшена до 0. Если память невелика, система уменьшит ненужное представление и вызовет метод viewDidUnload, он автоматически уменьшит панель toolCount до 0. Таким образом, в методе dealloc я должен установить панель на нуль. Я запутался, если я установил панель инструментов в нуль, когда вызывается метод viewDidUnload, панель инструментов будет уменьшена или нет? Происходит ли утечка по меторике?

Thx.

+0

Но для памяти subview, когда subview будет выпуском релиза, он должен вызывать только низкую память и метод viewDidUnload? – Golden

+0

Тест в приборах для утечки памяти. Проверка таких показателей не даст вам ничего. – danielbeard

+1

Вы никогда не должны использовать 'keepCount': http://stackoverflow.com/questions/11028512/addsubview-and-dealloc-for-memory-leaks-retaincount#comment14420031_11028512 – rckoenes

ответ

2

Во-первых, если ваш код отражает ваш реальный код, ваш метод dealloc имеет большой вопрос:

- (void) dealloc{ 
    [toolbar removeFromSuperView]; 
    [toolbar release] 
    toolbar = nil; 
} 

вы не вызывая [super dealloc]. Не вызывая [super dealloc], self.view никогда не будет выпущен (и в конечном итоге освобожден).

Это должно зафиксировать ваши утечки памяти (частично, по крайней мере):

- (void) dealloc{ 
    [toolbar release]; 
    [super dealloc]; 
} 

Вы можете заметить, что я удалил вызов removeFromSuperView, потому что это автоматически делается для вас, когда self.view фактически высвобождены, так что вы не нужно делать это самостоятельно. В любом случае вызов removeFromSuperView также не вызывает никаких проблем.

О ваших вопросах, я предполагаю, что ваше имущество toolbar объявлено как retain (на основе кода, который вы отправляете, это самая чувствительная гипотеза для меня).

Если toolbar является retain ребенком собственности, то правильный способ присвоить ему вновь созданный вид является:

toolbar = [[[UIToolbar alloc] initWithFrame:nil] autorelease]; 

пожалуйста, обратите внимание на autorelease; если его нет, ваши вызовы сохранения/выпуска нарушены. которые могли бы объяснить необходимость для вас, чтобы сначала вызвать release затем nil недвижимость в dealloc:

- (void)dealloc { 
... 
    [toolbar release] 
    toolbar = nil; 
.... 
} 

, делая так вы отпускаете toolbar дважды; но так как вы не использовали autorelease при назначении сохранению свойства, это приведет к правильному результату.

а) на панели инструментов вызовите removeFromSuperView и релиз API, результат тот же, панель инструментов retainCount только станет равным 1. Таким образом, если я проверить код использовать только каждый из них, результат тот же. Итак, могу ли я заключить, что пользователь может только назвать каждый API в порядке?

, как я сказал, что вам не нужно звонить непосредственно removeFromSuperView получить подвид будет выпущен в dealloc время, так как self.view будет делать это за вас. Другое дело, когда вы хотите удалить subview, сохраняя при этом superview (представьте, что вы показываете ярлык, а затем удаляете его); в этом случае вам нужно позвонить обоим, иначе у вас будет утечка.

б) Из яблок документе подтаблица добавляется к виду себя, вид самостоятельный имеет остается панель ручки, так что в методе dealloc, если viewDidUnload не называется, панель retainCount не может быть уменьшите до 0. Если память невелика, система уменьшит ненужное представление и вызовет метод viewDidUnload, он автоматически уменьшит панель toolCount до 0. Таким образом, в методе dealloc я должен установить панель на нуль. Я запутался, если я установил панель инструментов в нуль, когда вызывается метод viewDidUnload, панель инструментов будет уменьшена или нет? Происходит ли утечка по меторике?

, если я понимаю ваши сомнения правильно, дело в том, что если вы послали toolbar свойство nil в viewDidUnload, а затем, когда этот метод вызывается (или когда вы явно удалить точку зрения или когда предупреждение памяти выдается) ваше подчинение правильно утилизировано; если dealloc для вашего контроллера называется впредь, ваша собственность уже имеет значение nil, поэтому его выпуск не будет иметь никакого эффекта (но это нормально, поскольку он уже был выпущен в viewDidUnload).

С другой стороны, если вы не отпускаете недвижимость в viewDidUnload то, что происходит в том, что в случае, если отображается вид снова после предупреждения памяти, а затем loadView/viewDidLoad вызывается снова; но в этом случае, когда вы создаете подпрограмму панели инструментов и назначаете ее ссылку на свойство toolbar (при условии, что это retain вид), тогда старый объект автоматически освобождается для вас, так что у вас нет утечки памяти; происходит то, что вы используете немного больше памяти, которую вы могли бы сделать (поскольку панель инструментов не освобождается до тех пор, пока не будет создана self.view).

+0

Извините, я fogot, чтобы линия супер. – Golden

+2

Вы забыли: «saveCount бесполезен. Не называйте это». – bbum

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