Хитрое управление памятью в target-c - PullRequest
0 голосов
/ 02 ноября 2010

После прочтения: Управление памятью контроллера представления в Objective-c

и

Действительно ли addSubview UIView сохраняет представление?

Я написал следующий код для переключения подпредставления:

@synthesize switchableView, viewSelector, currentSubview;

//...

if(switchableView.subviews.count != 0)
 [[switchableView.subviews objectAtIndex:0] removeFromSuperview]]
self.currentSubview = (veiwSelector.selectedSegmentIndex == 0) ?
 [ViewA new] : [ViewB new];
[switchableView addSubview:currentSubview.view];

//[currentSubview release]; //<---crashes if I uncomment this line

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

Итак, давайте рассмотрим currentView:

  • A распределяется по «новому» сообщению - сохранить счет = A: 1

  • A удерживается установщиком - оставьте счет = A: 2

  • Представление А получает (предположительно) сохранение - сохранить счет = A: 2.1

в следующий раз через ...

  • Подвид А получает количество освобожденных = A: 2

  • B распределяется по «новому» сообщению - сохранить счет = B: 1, A: 2

  • A автоматически высвобождается установщиком - B: 1, A: 1

  • B удерживается установщиком - B: 1, A: 1

  • от А ничего не избавится?

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

Ответы [ 3 ]

5 голосов
/ 02 ноября 2010

Хорошо, шаг первый, игнорируйте retainCount. Это одна из тех вещей, которые Apple должна переименовать во что-то вроде lsdjiofsudfoiwjeriowhfiuwhrteiuhweifhsdjkfhsiurwoieuriosfho, чтобы люди не угадали его имя и не указали его в документации. Для ваших целей это совершенно бесполезно, поэтому игнорируйте его.

Теперь, когда я сказал это, давайте рассмотрим кое-что: addSubview: сохраняет свой аргумент, а removeFromSuperview освобождает получателя.

Наконец, трудно сказать, что такое currentSubview. У него есть свойство view, которое склоняется к ВК, однако способ его использования сам по себе указывает на его нормальное представление. Возможно, вы можете уточнить, чтобы я мог продолжить свой ответ.

0 голосов
/ 03 ноября 2010

Ваше понимание сохранения и выпуска верное, как и ваш код.Это говорит о том, что проблема лежит за пределами кода, который вы опубликовали.Например, у вас возникла бы эта проблема, если бы ваше свойство currentSubView было определено как assign вместо retain.

Однако ваш код структурирован неправильно.Это было бы намного понятнее:

self.currentSubView = [[ViewA new] autorelease];

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

0 голосов
/ 02 ноября 2010

Измените строку выпуска на

self.currentSubview = nil;

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

...