尝试由其他类加载时,TableView崩溃

时间:2012-03-27 04:42:59

标签: iphone ios uitableview memory uiviewcontroller

我有这个应用程序(联系人样式),您可以在其中向桌面视图添加实例,它可以很好地添加对象到列表中。该列表将它们完美地呈现给详细视图。我可以在我的MasterViewController(UITableViewController,Nav控制器的rootControler)中多次调用“添加项”(带有TableView的UIViewController)视图。

当我看到这个工作,并希望扩展我的应用程序的功能让用户编辑列表中的当前对象时,我在detailView的导航控制器中添加了一个“编辑”按钮,这个UiBarButton触发了一个尝试加载用于在表View中添加Item的相同“Add Item”视图的方法。这是奇怪的事情开始发生的地方。

如果我运行应用程序并点击列表视图中的现有对象,我将成功进入详细视图。如果我然后点击“编辑”按钮,“添加项目”视图将很好地加载它当前正在编辑的对象的数据。然后,只要我从详细信息视图中调用它,我就可以多次取消/保存/关闭“添加项目”视图。如果我然后返回列表视图并尝试添加项目,则应用程序崩溃。

如果我启动应用程序,在其他任何地方之前,我从主列表视图加载“添加项目”,视图将完美加载,并且我可以根据需要完美地添加对象。如果我然后转到详细信息视图并尝试编辑对象,则应用程序崩溃。

简单放(如果你上面懒得阅读):每当我尝试从不同的控制器加载“添加项目”视图时,应用程序崩溃了第一次。

这是崩溃日志:

    *** Assertion failure in -[UITableView _createPreparedCellForGlobalRow:withIndexPath:], 
    /SourceCache/UIKit_Sim/UIKit-1914.84/UITableView.m:6061
     2012-03-26 21:22:49.087 Vex Try 5[2749:f803] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason:
    'UITableView dataSource must return a cell from tableView:cellForRowAtIndexPath:'
    *** First throw call stack: ...

显然,第二次尝试加载时,cellForRowAtIndexPath正在返回一个奇怪的单元格。

以下是我在列表视图中调用它的方式:

- (void)insertNewObject:(id)sender
    {
        if (!_objects) {
             _objects = [[NSMutableArray alloc] init];
        }

        BIDVexTeam *newTeam = [[BIDVexTeam alloc] init];
        [_objects insertObject:newTeam atIndex:0];

        if (!self.addNew) {
            self.addNew = [[BIDEditViewController alloc] init];
        }

        if (!self.editNavController) {
            self.editNavController = [[UINavigationController alloc] initWithRootViewController:self.addNew];
        }

        addNew.title = @"Add New";
        addNew.team = newTeam;
        addNew.parent = self;

        [self presentModalViewController:self.editNavController animated:YES];

    }

以下是我从详细信息视图中调用它的方式:

    - (IBAction)editTeam:(id)sender {

        if (!self.editView) {
            self.editView = [[BIDEditViewController alloc] initWithNibName:@"BIDEditViewController" bundle:[NSBundle mainBundle]];
        }

        if (!self.editNavController) {
            self.editNavController = [[UINavigationController alloc] initWithRootViewController:self.editView];
        }

        editView.title = [NSString stringWithFormat:@"Edit %@", detailTeam.number];
        self.editView.team = self.detailTeam;

        [self presentModalViewController:editNavController animated:YES];
    }

编辑:这是我的cellForRowAtIndexPath方法...没有粘贴在这里,因为它很长,以及我想要实现的截图:

http://www.clubpenguinaccess.com/extra/cellforrow-method.rtf

screenshot http://www.clubpenguinaccess.com/extra/app-screenshot.png

2 个答案:

答案 0 :(得分:0)

这肯定表明可能会崩溃。执行此操作的任何行:

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
如果已经分配了可重用的单元格,

...可能会返回nil。在某些情况下,您可以进行分配,例如:

} else if (indexPath.row == kImageRow) {

    static NSString *ImageCellIdentifier = @"ImageCell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ImageCellIdentifier];
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ImageCellIdentifier];
        cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
    }

..但不是其他几个人。崩溃的一个很好的假设是,它正在运行一条路径,其中没有触发任何单元格分配。

请搜索所有出列呼叫,添加检查nil返回,并分配适当的单元格。我认为你的崩溃将得到解决。

答案 1 :(得分:0)

我认为问题出在你的默认情况下。在某些情况下,您直接使用dequeueReusableCellWithIdentifier:,仅在已创建单元格以防止重复内存分配时才起作用。如果不先创建单元格,则无法重复使用单元格。所以我的猜测是,在某些情况下,您的单元格在不首先创建的情况下被重用