对于大多数具有侧边菜单功能的应用,我使用 MFSideMenu 控制器。所有应用程序在iOS 7及之前的版本上运行良好,但不适用于运行iOS 8的iPhone 6设备(在运行iOS8的iPhone 5上正常工作)。
我似乎无法弄清楚如何解决我收到的这个错误。单击LeftMenu UITableView上的单元格时,应用程序崩溃并发出此错误。
Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'An instance 0x7fc492877e00 of class UITableView was deallocated while key value observers were still registered with it. Current observation info: <NSKeyValueObservationInfo 0x7fc492634860>
注意:UITableView是一个XIB IBOutlet
这就是代码的外观
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
// This will remove extra space on top of the tableview
self.automaticallyAdjustsScrollViewInsets = NO;
// This will remove extra separators from tableview
self.tblViewMenu.tableFooterView = [[UIView alloc] initWithFrame:CGRectZero];
// menu titles
arrMenu = [Config returnArrLeftMenu];
// check login status
[self checkLoginStatus];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CustomCellIdentifier = @"CustomCellIdentifier ";
MenuCell *mCell = (MenuCell *)[tableView dequeueReusableCellWithIdentifier: CustomCellIdentifier];
// menu cell
if (mCell == nil) {
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"MenuCell" owner:self options:nil];
for (id oneObject in nib) if ([oneObject isKindOfClass:[MenuCell class]])
mCell = (MenuCell *)oneObject;
}
mCell.selectionStyle = UITableViewCellSelectionStyleBlue;
mCell.contentView.backgroundColor = [UIColor clearColor];
mCell.backgroundColor = [UIColor clearColor];
mCell.lblTitle.text = [arrMenu objectAtIndex:indexPath.row];
return mCell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// load selected menu view on to the MAinViewController
MainViewController *mainController = [[MainViewController alloc] initWithNibName:@"MainViewController" bundle:nil];
mainController.title = [arrMenu objectAtIndex:indexPath.row];
mainController.menuIndex = (int)indexPath.row;
UINavigationController *navigationController = self.menuContainerViewController.centerViewController;
NSArray *controllers = [NSArray arrayWithObject:mainController];
navigationController.viewControllers = controllers;
[self.menuContainerViewController setMenuState:MFSideMenuStateClosed];
}
答案 0 :(得分:11)
您可能会使用以下代码观察TableView的属性更改:
[self.tblViewMenu addObserver:self forKeyPath:@"frame" options:NSKeyValueObservingOptionNew context:nil]
对观察者(您的类实例)的引用与不安全的未保留语义一起存储。您必须在dealloc()期间清理它以避免应用程序崩溃(ARC无法为您处理此问题)。
所以你的dealloc()应该取消注册这样的观察者:
- (void)dealloc {
[self.tblViewMenu removeObserver:self forKeyPath:@"frame"];
}
您必须将“frame”替换为您感兴趣的属性的名称。
务必在正确的Apple Guide
中检查键值观察(KVO)的基本概念修改强>
我刚检查了MFSideMenu的源代码。该代码中没有KVO使用的迹象,因此崩溃可能不是由该组件引起的。
答案 1 :(得分:4)
对于swift版本,您可以使用&#34; deinit&#34;删除所有观察者的方法
deinit {
self.yourtable.removeObserver(self, forKeyPath: "keyname")
}
答案 2 :(得分:0)
在取消分配控制器之前,您确定您的tableView实际上已正确清理吗?尝试向控制器添加-(void) dealloc{}
方法并在其中添加断点。如果你的控制器在调用dealloc时仍然引用tableView,那么它将导致你看到的那种问题。
如果是这种情况,那么您需要覆盖removeFromParentViewController
控制器的方法并手动将tableView属性设置为nil。例如:
-(void) removeFromParentViewController {
[super removeFromParentViewController];
if(self.tableView!=nil) {
self.tableView.delegate = nil;
self.tableView.dataSource = nil;
self.tableView = nil;
}
}
希望有所帮助!