在 iPhone 的 Objective-C 中在 (commitEditingStyle) 之外调用 (deleteRowsAtIndexPaths)

Posted

技术标签:

【中文标题】在 iPhone 的 Objective-C 中在 (commitEditingStyle) 之外调用 (deleteRowsAtIndexPaths)【英文标题】:Calling (deleteRowsAtIndexPaths) outside of (commitEditingStyle) in Objective-C for the iPhone 【发布时间】:2011-01-12 06:40:07 【问题描述】:

我有一个自定义UITableViewCell,其中添加了两个自定义UIButton。在其中一个按钮上,我希望能够从myMethod() 中删除单元格行。

该方法被addTarget:@selector(myMethod:)cellForRowAtIndexPath内调用:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
    ...
    cell.acceptButton.tag = indexPath.row;
    [cell.contentView addSubview:acceptButton];

    [cell.acceptButton addTarget:self action:@selector(myMethod:) forControlEvents:UIControlEventTouchUpInside];

这样行,实际方法调用成功。

- (void)myMethod:(id)sender 
   NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow]; //works fine (correct indexPath is returned)
   friendsArray removeObjectAtIndex:indexPath.row]; //works fine (correct indexPath.row is returned and the object is removed from the array)
   [tv deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade]; //throws error below

错误:

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[NSArray initWithObjects:count:]: attempt to insert nil object at objects[0]'
*** Call stack at first throw:
(
 0   CoreFoundation                      0x020a9be9 __exceptionPreprocess + 185
 1   libobjc.A.dylib                     0x021fe5c2 objc_exception_throw + 47
 2   CoreFoundation                      0x01ff3ffe -[__NSPlaceholderArray initWithObjects:count:] + 494
 3   CoreFoundation                      0x020158a3 +[NSArray arrayWithObject:] + 67
 4   MyApp                          0x00071d1b -[FriendListViewController myMethod:] + 417
 5   MyApp                          0x00020b87 -[MBProgressHUD launchExecution] + 151
 6   Foundation                          0x004a3d4c -[NSThread main] + 81
 7   Foundation                          0x004a3cd8 __NSThread__main__ + 1387
 8   libSystem.B.dylib                   0x9461f85d _pthread_start + 345
 9   libSystem.B.dylib                   0x9461f6e2 thread_start + 34

通常我会在删除单元格中的一行时这样做。这工作正常:

- (void)tableView:(UITableView *)tableview commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath 
 if(editingStyle == UITableViewCellEditingStyleDelete) 
  //Delete the object from the friends array and the table.
  [friendsArray removeObjectAtIndex:indexPath.row];
  [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
 

【问题讨论】:

介意添加解决方案吗?我刚刚遇到了类似的问题。 【参考方案1】:

如果您在每个单元格或多个单元格上使用 uibutton 并设置相同的选择器,则查找单元格的最佳选择是使用标签。

当我想将附件按钮的颜色更改为绿色时,我这样做了(我不知道苹果是否允许这样做,但我只是想尝试一下)。所以制作了一个自定义按钮并将其背景图像更改为绿色,然后在附件视图中我添加了该按钮。它工作得很好。需要在tableView:cellForRowAtIndexPath:方法中设置标签

【讨论】:

我实际上发现了问题所在。如果未选择实际行,则同一行将引发错误。如果它被选中,那么它工作得很好。那么是否有另一种方法可以在没有实际选择的情况下删除该行? @robin: indexPath 是一个 NSIndexPath 对象,而不是行号。 @Fulvio:如果要删除未选中的行,则必须已经知道单元格的索引路径是什么。 UITableView 具有获取给定单元格对象或单元格内屏幕上的点的单元格索引路径的方法。 我已将按钮的标签设置为 cellForRowAtIndexPath 中的 indexPath.row。但是,即使我选择列表中的第二行,标签也总是返回 0。 @robin 我用我用来标记 cellForRowAtIndexPath 中的按钮的代码编辑了我的原始问题。 @robin 哇哦!我弄清楚了这个问题。我在 ivar 上错误地设置了标签。【参考方案2】:

问题在于数组初始化,而不是行删除。尝试再次调试此方法并检查 indexPath 是否可以为 nil。

【讨论】:

它不是 nil 并且数组已正确初始化。 @Fulvio:好吧,运行时不同意你的观点:'*** -[NSArray initWithObjects:count:]:尝试在 objects[0] 处插入 nil 对象' 问题出在 commitEditingStyle 方法中,因为它在 ios 库内部崩溃。

以上是关于在 iPhone 的 Objective-C 中在 (commitEditingStyle) 之外调用 (deleteRowsAtIndexPaths)的主要内容,如果未能解决你的问题,请参考以下文章

在objective-c中在哪里设置窗口大小iOS?

在 Objective-C 中在矩形周长上投影一个点

是否可以在 iPhone 上的 phonegap 应用程序中在后台跟踪 gps 位置?

在 iphone/ipad 应用程序中在哪里添加加载视图?

iPhone(Objective-c)和Java之间的AES区别

在 Objective-C (iPhone) 中卸载视图