【问题标题】:NSMutableArray removeObjectAtIndex:indexPath.row crashesNSMutableArray removeObjectAtIndex:indexPath.row 崩溃
【发布时间】:2011-07-11 09:28:35
【问题描述】:

我有一个 UITableViewController,标题中有一个 NSMutableArray,如下所示:

NSMutableArray *someArray;

我还声明了属性:

@property (nonatomic, retain) NSMutableArray *someArray;

在 .m 文件中,我在方法中加载数组:

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];

    someArray = [[NSMutableArray alloc] init];

    [self loadArrayData];

    [tableview reloadData];
}

表格填充得很好,添加没问题,但是当我尝试删除一行时,应用程序在以下行崩溃:

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {

    if (editingStyle == UITableViewCellEditingStyleDelete) {

    [someArray removeObjectAtIndex:indexPath.row];

    //update table etc..

如果我使用调试器,我可以看到数组有一些对象,当我记录 indexPath.row 时,我得到一个在数组大小内的值。

我不明白为什么它在这条线上崩溃...谁能帮助我?

控制台输出:

* 由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因:“-[__NSArrayI removeObjectAtIndex:]:无法识别的选择器已发送到实例 0x6193890”

【问题讨论】:

  • 有关崩溃原因的更多信息可能会有所帮助。发生了什么样的崩溃?
  • 对不起,我已经添加了控制台错误输出..
  • 嗯,我真的不知道。很明显,一个无效的参数被传递给 removeObjectAtIndex:。然而 indexPath.row 应该返回一个 NSUInteger 这是一个有效的参数。
  • 这和我想的一模一样...同样将值 0 传递给方法会导致它崩溃...
  • 并且您 100% 确定该数组不会在某个地方被不可变数组替换?再次检查。

标签: iphone xcode ios4 ipad


【解决方案1】:

我遇到了一个非常相似的问题,我正在使用 CoreData 启动我的数组,如下所示:

self.allContacts = (NSMutableArray*)[cdc.managedObjectContext executeFetchRequest:fetchRequest error:&error];

尝试将 CoreDataController 获取请求的结果转换为 NSMutableArray。

原来我需要在获取请求结束时使用名为“mutableCopy”的函数。

self.allContacts = (NSMutableArray*)[[cdc.managedObjectContext executeFetchRequest:fetchRequest error:&error] mutableCopy];

我认为不需要强制转换为 (MutableArray *),但我有它以防万一。

希望这会有所帮助。

【讨论】:

    【解决方案2】:
    1. 不确定这是否会导致您的问题之一,但如果您有 someArray 的属性,请使用 self.someArray 而不仅仅是 someArray 。 当然,使用 self 后,你应该像这样自动释放它:

    self.someArray = [[[NSMutableArray alloc] init] autorelease];

    (在你的 viewController 中调用这个 初始化方法)

    然后尝试:

    [self.someArray removeObjectAtIndex:indexPath.row];
    

    2。 尝试在viewDidLoad 中调用[self loadArrayData];。 它应该在 cellForRowAtIndexPath 之前调用,这样你就不需要调用reloadData

    如果仍然没有帮助,请发布loadArrayData的代码

    【讨论】:

    • 嗨,我回家后试试。我调用 reloadData 的问题是因为我有一个导航控制器,它有一个“添加”按钮,它将视图推送到用户可以输入一些细节的新视图,当他点击“保存”时,导航控制器会弹出并那么它必须重新加载数据,因为用户刚刚输入了一条新记录......如果没有 reloadData 我怎么能做到这一点?
    • 您可以将要更新的数组传递给新的 viewController 并在那里进行更新。当您返回 tableViewController 时,tableView 不会自行重新加载吗?不要认为你需要调用 reloadData。
    【解决方案3】:

    一周前我遇到了同样的问题。我所做的是:

    在同一个 tableViewController.m 实现文件中将 NSMutableArray* globalArray 声明为全局。然后在里面

    if (editingStyle == UITableViewCellEditingStyleDelete) {
       globalArray = [[NSMutableArray alloc] initWithArray:someArray];
       [globalArray removeObjectAtIndex:[indexPath row]]; 
    }
    

    然后我在 reloadData 调用之前将此 globalArray 复制回 someArray 中。作品。

    【讨论】:

    • 嗨。感谢您的回复!它解决了我面临的问题,但现在它在 UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];在 tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 任何想法如何解决这个问题?
    • 你不应该用这样的黑客“修复”你的错误。
    • 很好的答案,@Bourne。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多