TextFieldDelegate освобождается слишком рано - PullRequest
0 голосов
/ 12 октября 2010

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

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 становитсяосвобожден (и, следовательно, освобожден), потому что это свойство сохраняющего типа.Проблема в том, что если мой TextField был FirstResponder при нажатии кнопки перезагрузки, он по-прежнему отправляет свои textFieldShouldEndEditing, textFieldEditorDidChangeSelection и т. Д. Сообщения в освобожденный теперь ClientDetailsDelegate.Похоже, что эти сообщения должны быть отправлены до того, как будет выполнен любой из приведенных выше кодов, потому что TextField теряет фокус в момент нажатия кнопки.Кроме того, после вызова removeFromSuperview само TextField больше не должно существовать.

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

1 Ответ

0 голосов
/ 12 октября 2010

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

self.detailsViewController.detailsDelegate = detailsDelegate;

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


С другой стороны:

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 не является вашим собственным классом и вы не сохранили свойство делегата).

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