【问题标题】:TableView crashing when trying to be loaded by a different class尝试由其他类加载时 TableView 崩溃
【发布时间】:2012-04-10 15:02:31
【问题描述】:

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

当我看到这行得通,并想扩展我的应用程序的功能以让用户在列表中编辑他们当前的对象时,我在 detailView 的导航控制器中添加了一个“编辑”按钮,这个 UiBarButton 触发一个尝试加载用于在表视图中添加项目的相同“添加项目”视图的方法。这就是奇怪的事情开始发生的地方。

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

如果我启动应用程序,并且在其他任何事情之前,我从主列表视图加载“添加项目”,该视图将完美加载,并且我可以完美地添加对象任意多次。如果我随后转到详细视图并尝试编辑对象,应用程序就会崩溃。

简单地说(如果您懒得看上面的内容):每当我尝试从与加载它的控制器不同的控制器加载“添加项目”视图时,应用程序就会崩溃第一次。

这是崩溃日志:

    *** 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

【问题讨论】:

  • 已发布。太长了,所以我上传了 rtf 格式(这样可以保留 Xcode 的颜色)

标签: iphone ios uitableview memory uiviewcontroller


【解决方案1】:

这当然表明有崩溃的可能性。执行此操作的任何行:

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

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

请搜索所有出队调用,添加一个零返回检查,并分配一个适当的单元格。我认为您的崩溃将得到修复。

【讨论】:

  • 哇,解决了崩溃问题!谢谢,永远不会想到这一点.. 但是,如果我希望它加载一个 nib 文件,我该如何初始化单元格?我试过这个:cell = [[BIDStandardCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:StandardCellIdentifier]; 在 if (cell == nil) 条件下得到了这个:link
  • 还尝试了一个简单的cell = [[BIDStandardCell alloc] init],但得到了相同的结果:\ 对此有何提示?
  • 看起来您可以从笔尖成功加载一些单元格(如上面的 ImageCell sn-p),您可以重复使用该方法吗?
【解决方案2】:

我认为问题出在您的默认情况下。在某些情况下,您直接使用了dequeueReusableCellWithIdentifier:,这仅在已创建单元格以防止重复的内存分配时才有效。如果不先创建单元格,您将无法重复使用它。所以我的猜测是,在某些情况下,您的单元格在没有被创建之前就被重复使用了

【讨论】:

    猜你喜欢
    • 2018-07-31
    • 1970-01-01
    • 2019-09-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多