开发者

TextFieldDelegate being deallocated too early

My program is crashing because my TextField is sending messages to its delegate after the delegate has been deallocated. I have an object that serves as a UITableViewDataSource and a UITextFieldDelegate. In cellForRowAtIndexPath, I create a TextField inside each TableViewCell and assign self as the TextField's delegate. When I click a button on the screen, the view reloads (it runs all the same code that is run when the view was loaded the first time):

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.currentCl开发者_如何学运维ient.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; causes the previous ClientDetailsDelegate to be released (and therefore dealloced), because it is a retain-type property. The problem is that if my TextField was the FirstResponder when the reload button is clicked, it still sends it's textFieldShouldEndEditing, textFieldEditorDidChangeSelection, etc, messages to the now dealloced ClientDetailsDelegate. It seems like those messages should get sent before any of the above code is executed, because the TextField is losing focus the moment the button is clicked. Also, once the removeFromSuperview is called, the TextField itself shouldn't exist anymore anyway.

How can I make sure that the TextField is destroyed when I reload the view, and prevent it from sending messages to its delegate after the delegate has been dealloced?


The text field only sends those messages after all this stuff has happened possibly because the current control might refuse to accept first responder. Anyway, the reason is not important. The point is you are destroying a delegate before a control that uses it has finished with it. Before the line:

self.detailsViewController.detailsDelegate = detailsDelegate;

you need to set the delegate property of the control that the old delegate was for to nil. You could probably do it in the dealloc method of the delegate object.


On another note:

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];

looks wrong. None of the properties you assign menuDelegate to are retain properties. I think it will go away as soon as you release it leaving dangling pointers (unless menuViewController is your own class and you have made the delegate property retain).

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜