Objective-C сохранить вопрос - PullRequest
0 голосов
/ 12 апреля 2011

В Xcode у меня есть UINavigationController, на котором я нажимаю UIViewController.

В этом UIViewController я запускаю UIScrollView.

Все хорошо.

Однако, после переключения в другое представление, я записываю счетчик сохранений контроллера, и, к моему удивлению, он равен нулю.

Вот код:

scroller = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];

[self.view addSubview:scroller];

и

- (void)dealloc {
    [super dealloc];

    NSLog(@"retaincount, %d", [scroller retainCount]);  //displays 2

    [scroller release];

    NSLog(@"retaincount, %d", [scroller retainCount]); // displays 1
}

Я только инициирую его и добавляю в представление UIViewControllers.

С уважением,

Tom

Ответы [ 4 ]

4 голосов
/ 12 апреля 2011

Не используйте retainCount! Из яблочной документации :

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

Чтобы понять основные правила управления памятью, которые вы должны соблюдать, прочтите « Правила управления памятью ». Для диагностики проблем управления памятью используйте подходящий инструмент:

  • Статический анализатор LLVM / Clang обычно может обнаруживать проблемы с управлением памятью даже до запуска вашей программы.
  • Инструмент Object Alloc в приложении Instruments (см. Руководство пользователя Instruments ) может отслеживать распределение и уничтожение объектов.
  • Shark (см. Руководство пользователя Shark ) также профилирует распределение памяти (среди множества других аспектов вашей программы).

Сказав это: Вы должны вызвать [super dealloc] в самой последней строке вашего dealloc метода. Кроме того, все в вашем коде должно быть в порядке. Не пытайтесь вручную уменьшить retainCount. Используйте правильное управление памятью. Опять же, не смотрите на retainCount.

И вам не разрешено использовать объект после того, как вы его отпустили. Если скроллер будет освобожден из-за вашего освобождения, второй NSLog приведет к исключению BAD_ACCESS.

1 голос
/ 12 апреля 2011

Предыдущие ответы верны: не используйте -retainCount, и убедитесь, что вы вызываете [super dealloc] last в своей собственной реализации -dealloc.

Я хочу добавить, что вы, вероятно, никогда не увидите случай (не то, что вы должны искать), где -retainCount возвращает 0. Если объект retainCount падает до нуля, объект освобождается. Фактически, кажется, что Какао никогда даже не удосуживается установить нулевое значение retainCount ... -релиз освобождает объект, если предыдущий retainCount был равен 1. Еще одна причина считать -retainCount частной реализацией.

1 голос
/ 12 апреля 2011

self.view сохраняет его. Когда ваш UIViewController освободит, он выпустит self.view, что освободит все его сохраненные подпредставления. На самом деле, вы должны выпустить его вскоре после добавления в self.view.

Тем не менее, я решительно второй ответ @ fluchtpunkt. Изучение свойства retainCount в поисках отладочной информации приведет только к путанице и все более последовательным и беспорядочным публикациям в Stack Overflow.

1 голос
/ 12 апреля 2011

Вот почему:

scroller = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
//retain count = 1

[self.view addSubview:scroller];
//retain count + 1 + 1 = 3

//later the AutoreleasePool decrements the count by 1, resulting in a retain count of 2.
  1. Методы, начинающиеся с init… возвращать неавторизованные экземпляры со счетом сохранения 1.
  2. Доступ к вашему subview через self.view: возвращает автоматически освобожденный сохраненный указатель на subview.
  3. Добавление подпредставление для просмотра через addSubview: сохраняет подтаблицы .
  4. Удаление подпредставления из его суперпредставления через removeFromSuperview: освобождает его .

Вы не должны полагаться на счет сохранения объекта.
Вместо этого вы должны позаботиться о том, чтобы выровнять удержание и отпускание вызовов для объекта. Обязательно прочитайте Apple Руководство по программированию управления памятью по этому вопросу! (в частности, раздел правил !)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...