NSMutableArray removeObjectAtIndex:indexPath.row crashes NSMutableArray删除indexPath.row位置的对象时崩溃

3

我有一个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时,我得到的值在数组大小之内。我不明白为什么它会在这一行崩溃...谁能帮助我?控制台输出: * Terminating app due to uncaught exception 'NSInvalidArgumentException' ,原因是:'-[__NSArrayI removeObjectAtIndex:]:向实例0x6193890发送未识别的选择器。'

1
提供更多有关崩溃的信息可能会有所帮助。发生了什么样的崩溃? - Brenton Morse
抱歉,我已经添加了控制台错误输出。 - CyberK
嗯,我真的不知道。很明显,removeObjectAtIndex:方法被传递了一个无效的参数。然而,indexPath.row应该返回一个NSUInteger类型的有效参数。 - Brenton Morse
4
你能否再次确认,数组在某个地方是否被替换为不可变数组?请再检查一遍。 - Matthias Bauch
我有一个非常类似的问题。有趣的是,前25个对象都可以轻松删除,但从第26个开始就出现了问题。 - John Smith
显示剩余2条评论
3个回答

2

我有一个非常类似的问题,我正在使用CoreData初始化我的数组,像这样:

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

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

结果发现我需要在获取请求结尾处使用名为"mutableCopy"的函数。

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

我认为不需要将其转换为(MutableArray *),但以防万一我还是这样做了。
希望这可以帮到你。

1

我在一周前遇到了同样的问题。我的解决方法如下:

在同一个tableViewController.m实现文件中,声明了一个NSMutableArray* globalArray作为全局变量。然后在内部进行操作。

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

然后,在调用reloadData之前,我将globalArray复制回someArray。可以正常工作。

嗨。谢谢你的回复!它解决了我遇到的问题,但现在它在tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath中的UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];这一行崩溃了。有什么想法如何解决这个问题吗? - CyberK
3
不应该用这种方法来“修复”你的漏洞。 - Matthias Bauch
很好的回答,@Bourne。谢谢! - Adela Toderici

0
  1. 不确定这是否导致了你的问题之一,但如果你有一个名为someArray的属性,则应该使用self.someArray而不是只使用someArray。 当然,在使用self之后,你应该像这样自动释放它:

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

(在你的视图控制器初始化方法中调用)

然后尝试:

[self.someArray removeObjectAtIndex:indexPath.row];

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

如果仍然无法解决问题,请发布 loadArrayData 的代码


嗨,我回家后会尝试一下。我调用reloadData的问题是因为我有一个导航控制器,它有一个“添加”按钮,它将视图推到一个新视图,用户可以在其中输入一些详细信息,当他点击“保存”时,导航控制器被弹出,然后必须重新加载数据,因为用户刚刚输入了一个新记录...如何在不使用reloadData的情况下完成这个任务? - CyberK
你可以将要更新的数组传递给新的视图控制器,并在那里进行更新。而且当你返回到表视图控制器时,表格视图不是会自动重新加载吗?我觉得你不需要调用reloadData方法。 - Idan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接