2015-04-27 4 views
0

У меня есть UITableView, в каких ячейках содержится один UITextField. Мой UITableViewController является делегатом всех этих текстовых полей. Теперь, когда UITableViewController получает освобождение, я хочу установить делегат всех этих текстовых полей на нуль. Текстовое поле имеет тег, поэтому я могу получить его по тегу, когда у меня есть ячейка.UITableViewCell: установите делегат UITextField на nil в dealloc

Вопрос в том, как получить все созданные ячейки? Запрашивая UITableView для visibleCells возвращает только видимые ячейки, но может случиться, что есть строка, которая не видна, бит ее по-прежнему имеет UIViewController в качестве делегата. Поэтому мне действительно нужно как-то собрать все созданные ячейки. cellForRowAtIndexPath делает то же самое, поэтому для меня это тоже не сработает. Единственный способ, который я вижу здесь, - хранить все текстовые поля в массиве, но может быть, есть лучший способ?

Вот код:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    UITableViewCell *cell = (UITableViewCell*)[tableView dequeueReusableCellWithIdentifier:@"reuseId"]; 
    if (cell == nil) 
    { 
     cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"reuseId"]; 
     UITextField *nameTextField = [[UITextField alloc] initWithFrame:nameTextFieldRect]; 
     nameTextField.tag = TEXT_FIELD_TAG; 
     nameTextField.delegate = self; 
     [cell.contentView addSubview:nameTextField]; 
    } 
    return cell; 
} 

-(void)dealloc 
{ 
    // todo: get all text fields and set theirs delegate to nil 
} 

Ну, большинство ответов свидетельствуют о том, что мне не нужно, чтобы установить делегат ноль, но, как я параноик, я подозреваю, что следующий сценарий возможно: Вызов кнопки «Назад», так вызывается dealloc моего view controller. В dealloc мой view controller выпускает табличный вид, но tableView все еще существует на этом этапе, а также все текстовые поля. И если каким-то образом одно из текстовых полей будет называть его методом делегирования, приложение будет разбиваться, потому что делегат больше не является допустимым объектом.

Если кто-то может объяснить, почему этот сценарий невозможен, он убедит меня, что мне не нужно устанавливать делегат на нуль.

+0

Вы создали пользовательскую ячейку для просмотра таблиц? – user3182143

+0

Как насчет того, чтобы ваши делегаты 'textField' были в nil, в 'prepareForReuse'? Таким образом, только видимые ячейки будут иметь своих делегатов, установленных в контроллере табличного представления. – n00bProgrammer

+0

нет необходимости делать это, по умолчанию делегаты имеют слабую ссылку на ячейку, после того как 'UITableViewController' освобожден, все ячейки также освобождены, а делегаты автоматически установлены на nil –

ответ

6

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

По умолчанию delegate является слабым ориентиром, поэтому он не сохранит ваш объект.

+0

См. Дополнение к моему вопросу, где я объясню, почему я не могу его принять. – Anastasia

+0

@ Анастасия: Здравый смысл в том, что если делегат не был слабой ссылкой, тогда UITableViewController не будет освобожден в первую очередь! Когда вызывается dealloc, там __cannot__ либо сильные, либо слабые ссылки на объект. Даже если комментарий Стефана Салатика был неправильным, там _still_ не может быть ссылкой на UITableViewController. – gnasher729

+0

Когда вы нажимаете назад, начинается цепочка освобождения. Сначала tableView начнет освобождение, которое освободит все ячейки, а затем прекратится освобождение таблицы, и только тогда VC будет освобожден. –

-1

Создайте новый делегат/протокол для этой ячейки и реализуйте этот делегат в контроллере представления, например PersonTableViewCellDelegate. Кроме того, ваша ячейка реализует делегат UITextField и в этом коде вызывает [self.delegate onKeyPressed] или что-то еще. Я рекомендую вам также передать ссылку на ячейку, поэтому в контроллере представления вы можете использовать indexPathFromCell (или что-то в этом роде), чтобы узнать положение ячейки. Если вам интересно, расскажите мне об этом и скопируйте код.

0

Я не ожидаю, что этот ответ будет отмечен как принятый, но это не будет вписываться в окно комментариев.

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

Если это не так, они, вероятно, имеют сильную ссылку на что-то еще, но это легко обнаружить с помощью профилировщика.

Я также хотел бы добавить, что при работе с ячейками действие прокрутки UITable, отбрасывание назад снова вводится в таблицу, прокручивайте назад (повторяется не менее 10 раз), это обязательная практика для обнаружения утечки памяти.

Кроме того, я не знаю, цель присвоения метки к камере, я, возможно, ошибаюсь, но с этим:

nameTextField.tag = TEXT_FIELD_TAG; 

считают, что у вас есть более одной ячейки с тем же тегом, поэтому вы не может просто вспомнить желаемый. Я помню, что это правило является первым помещенным на экране «выиграть» TAG (или вроде).

[UPDATE]

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

UITextView textView = [mainView viewWithTag:TEXT_FIELD_TAG]; 
while(textView!=nil){ // or whatever loop or criteria you like 
    // deallo, nil, etc... 
    textView = [mainView viewWithTag: TEXT_FIELD_TAG]; 
} 
+0

Я назначаю тэг текстовому полю внутри ячейки, так что я могу получить к нему доступ позже [[cell.contentView viewWithTag: TEXT_FIELD_TAG] '. – Anastasia

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