2010-10-12 7 views
0

Моя программа сбой, потому что мой TextField отправляет сообщения своему делегату после того, как делегат был освобожден. У меня есть объект, который служит UITableViewDataSource и UITextFieldDelegate. В cellForRowAtIndexPath я создаю TextField внутри каждого TableViewCell и назначаю себя как делегат TextField. При нажатии кнопки на экране, вид перезагружается (он работает все тот же самый код, который запускается, когда вид был загружен в первый раз):TextFieldDelegate освобождается слишком рано

DetailsViewController *controller = [[DetailsViewController alloc] initWithNibName:@"ClientView" bundle:nil]; 
self.detailsViewController = controller; 
[controller release]; 

NRFCAppDelegate *appDelegate = UIApplication.sharedApplication.delegate; 
for (UIView *view in [[[appDelegate.splitViewController.viewControllers objectAtIndex:1] view] subviews]) 
{ 
    [view removeFromSuperview]; 
} 
CGRect rect = [[[appDelegate.splitViewController.viewControllers objectAtIndex:1] view] frame]; 
self.detailsViewController.view.frame = CGRectMake(0, 0, rect.size.width, rect.size.height); 
[[[appDelegate.splitViewController.viewControllers objectAtIndex:1] view] addSubview:self.detailsViewController.view]; 

self.detailsViewController.detailsTitle.title = self.currentClient.name; 
self.menuViewController.clientLabel.text = self.currentClient.name; 

self.menuViewController.propertyLabel.text = @"Properties:"; 
self.menuViewController.addPropertyButton.hidden = NO; 
self.menuViewController.editPropertiesButton.hidden = NO; 

ClientMenuDelegate *menuDelegate = [[ClientMenuDelegate alloc] initWithRootController:self]; 
menuDelegate.properties = self.currentClient.properties.allObjects; 
self.menuViewController.tableView.delegate = self.menuViewController.tableView.dataSource = menuDelegate; 
self.menuViewController.delegate = menuDelegate; 
[menuDelegate release]; 

ClientDetailsDelegate *detailsDelegate = [[ClientDetailsDelegate alloc] initWithRootController:self]; 
detailsDelegate.client = self.currentClient; 
self.detailsViewController.tableView.delegate = self.detailsViewController.tableView.dataSource = detailsDelegate; 
self.detailsViewController.detailsDelegate = detailsDelegate; 
[detailsDelegate release]; 

[self.menuViewController.tableView reloadData]; 
[self.detailsViewController.tableView reloadData]; 

self.detailsViewController.detailsDelegate = detailsDelegate; вызывает предыдущий ClientDetailsDelegate быть освобожден (и, следовательно, dealloced), поскольку это свойство типа сохранения. Проблема заключается в том, что если мой TextField был первымResponder, когда нажата кнопка перезагрузки, он по-прежнему отправляет текстовые сообщения TextFieldShouldEndEditing, textFieldEditorDidChangeSelection и т. Д. В уже освобожденный ClientDetailsDelegate. Похоже, что эти сообщения должны отправляться до того, как какой-либо из вышеперечисленного кода будет выполнен, потому что TextField теряет фокус при нажатии кнопки. Кроме того, после вызова removeFromSuperview, TextField сам по себе больше не должен существовать.

Как я могу убедиться, что TextField уничтожен при перезагрузке представления и не позволяет ему отправлять сообщения его делегату после того, как делегат был освобожден?

ответ

0

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

self.detailsViewController.detailsDelegate = detailsDelegate; 

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


На другой ноте:

ClientMenuDelegate *menuDelegate = [[ClientMenuDelegate alloc] initWithRootController:self]; 
menuDelegate.properties = self.currentClient.properties.allObjects; 
self.menuViewController.tableView.delegate = self.menuViewController.tableView.dataSource = menuDelegate; 
self.menuViewController.delegate = menuDelegate; 
[menuDelegate release]; 

выглядит неправильно. Ни один из свойств, которые вы назначили menuDelegate, не сохраняет свойства. Я думаю, что это исчезнет, ​​как только вы отпустите его, оставив свисающие указатели (если menuViewController не является вашим собственным классом, и вы сохранили свойство делегата).

+0

Спасибо, это имеет смысл, но как я могу установить делегат TextField в nil? UITextFields добавляются как subview моего UITableViewCell в cellForRowAtIndexPath, поэтому у меня нет указателей на них в моем классе. Единственное, о чем я могу думать, это поддерживать отдельный массив указателей на мои текстовые поля; действительно ли я должен это делать? – GendoIkari

+0

О, и что касается menuDelegate (а также detailsDelegate), мои «menuViewController.delegate» и «detailsViewController.delegate» сохраняют свойства. Спасибо хоть. – GendoIkari

+0

Ну, я пошел вперед и создал NSArray, чтобы сохранить указатель на мои текстовые поля, и в моем методе dealloc я установил все их делегаты на нуль. Это устраняет проблему. Благодаря!! Мой первый вопрос о SO; определенно довольный. – GendoIkari

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