簡體   English   中英

TextFieldDelegate被釋放為時過早

[英]TextFieldDelegate being deallocated too early

我的程序崩潰,因為在委托已被釋放之后,我的TextField正在向其委托發送消息。 我有一個充當UITableViewDataSource和UITextFieldDelegate的對象。 在cellForRowAtIndexPath中,我在每個TableViewCell內創建一個TextField,並將self分配為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被銷毀,並防止它在取消分配委托后將消息發送到其委托?

文本字段僅在發生所有這些事情之后才發送這些消息,這可能是因為當前控件可能拒絕接受第一響應者。 無論如何,原因並不重要。 關鍵是要在使用委托的控件完成委托之前銷毀它。 上線之前:

self.detailsViewController.detailsDelegate = detailsDelegate;

您需要將舊委托用於的控件的delegate屬性設置為nil。 您可能可以在委托對象的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是您自己的類,並且您保留了委托屬性)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM