Управление памятью с помощью pushViewController - PullRequest
14 голосов
/ 10 мая 2011

Я все еще не очень хорошо разбираюсь в методах управления памятью и удивляюсь, может ли кто-нибудь объяснить мне это странное поведение.Рассмотрим эти 3 фрагмента кода, которые я тестировал:

DofView* dofView = [[DofView alloc] initWithNibName:@"DofView" bundle:nil];
NSLog(@"dof retain count = %d", [dofView retainCount]); 

Этот журнал: retain count = 1. Это нормально.

DofView* dofView = [[DofView alloc] initWithNibName:@"DofView" bundle:nil];
[dofView release];
NSLog(@"dof retain count = %d", [dofView retainCount]); 

Этот журнал: retain count = 1.Разве это не должно быть 0 ??

DofView* dofView = [[DofView alloc] initWithNibName:@"DofView" bundle:nil];
[self.navigationController pushViewController:dofView animated:YES];
NSLog(@"dof retian count = %d", [dofView retainCount]);

В этом журнале: retain count = 5. Я понятия не имею, почему его пять?

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

Спасибо!

Ответы [ 7 ]

2 голосов
/ 10 мая 2011

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

2 голосов
/ 10 мая 2011

Не полагайтесь на retainCount для анализа памяти. Просмотрите справочные документы по Управление памятью для получения дополнительной информации

1 голос
/ 10 мая 2011

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

Так почему же ваш объект все еще имеет счет удержания 1?

Поскольку этобыл освобожден - это уже не ваш объект, это просто свободная память!

Попробуйте сделать это:

NSObject* o = [[NSObject alloc] init];
NSLog(@"retain count = %d", [o retainCount]); 
[o retain];
NSLog(@"retain count = %d", [o retainCount]); 
[o release];
NSLog(@"retain count = %d", [o retainCount]); 
[o release];
NSLog(@"retain count = %d", [o retainCount]); 

Вы получите вывод

retain count = 1
retain count = 2
retain count = 1
retain count = 1

Вы можете ожидатьпоследняя строка, чтобы сказать 0, а не 1. Однако, это не будет беспокоить уменьшение счетчика хранения, если он будет выпущен - в чем смысл!

На самом деле, тот факт, что последняя строка выводит что-либовообще без сбоев повезло - поскольку объект был освобожден, ничто не останавливает использование этой памяти чем-то другим - теперь это просто случайные данные.Это именно та ошибка, которая приводит к аварийному завершению EXC_BAD_ACCESS:)

На самом деле вы получаете предупреждение анализатора компилятора об окончательном NSLog, потому что вы передаете сообщение объекту, который не существует,подробнее:)


Что касается счетчика удержания 5 - я могу только повторить другие ответы - вы не знаете, что происходит внутри объектов - просто потому, что вы вызывали удерживать только один раз, не означаетчто никто другой не называл retain:)

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

Если вы беспокоитесь о утечках, используйтепрофиль и проверь!

1 голос
/ 10 мая 2011

Когда использовать -retainCount?

сохранение счета кажется бесполезным

0 голосов
/ 10 мая 2011

не полагайтесь на счет удержания.Раньше я также пытался проверить сохранение количества для управления памятью, но это всегда смущает меня (проверьте эту ссылку, когда сохранение счета смущает меня [http://stackoverflow.com/q/5483357/644149]. Просто следуйте простой руководящей линии, тогда у вас не будет утечек памяти в ваших приложениях

когда вы используете alloc, new, copy, retain, вы также должны разблокировать этот объект. Simple

0 голосов
/ 10 мая 2011

Свойство retainCount зависит от того, как UINavigationController взаимодействует с контроллером, который вы нажимаете.Если он хранится в объекте UIViewController несколько раз, вам не о чем беспокоиться.Важно то, что когда вы используете этот объект, вы отпускаете его, когда он вам больше не нужен.

Например, в этом случае, так как вы перемещаете новый контроллер в навигатор, вы должны сделать следующее:

DofView* dofView = [[DofView alloc] initWithNibName:@"DofView" bundle:nil];
[self.navigationController pushViewController:dofView animated:YES];
[dofView release];

Вероятно, счетчик сохранения для объекта не обновляется мгновенно, поэтому вам не следует беспокоиться об этом числе.памяти, вы должны использовать инструменты профилирования внутри XCode (поиск утечек памяти).

Надеюсь, это поможет.

0 голосов
/ 10 мая 2011

Вызов release не вступает в силу немедленно, поэтому счетчик сохранения может выглядеть некорректно. Вы можете использовать инструмент «Утечки» для отслеживания проблем с памятью, но если вы следуете правилам mgmt памяти, с вами все будет в порядке.

...