Objective-C NSMutableArray removeObjectAtIndex:崩溃

Posted

技术标签:

【中文标题】Objective-C NSMutableArray removeObjectAtIndex:崩溃【英文标题】:Objective-C NSMutableArray removeObjectAtIndex: crashes 【发布时间】:2012-09-27 00:47:24 【问题描述】:

我有一个带有表格视图的视图控制器,您可以在其中删除单元格。我有另一个处理称为书签的类,该类称为BookmarkHandler。有一些方法可以上传书签、获取整个书签数组和删除书签。这里的类如下:

+ (NSMutableArray *)bookmarkCollection 

NSMutableArray *bookmarkCollection = [[NSUserDefaults standardUserDefaults] objectForKey: @"bookmarks"];

if (!bookmarkCollection) 

    bookmarkCollection = [[NSMutableArray alloc] init];


return bookmarkCollection;


+ (void)deleteBookmark: (NSIndexPath *)indexPath 

    NSMutableArray *bookmarkCollection = [[NSUserDefaults standardUserDefaults] objectForKey: @"bookmarks"];

    [bookmarkCollection removeObjectAtIndex: indexPath.row];

    [[NSUserDefaults standardUserDefaults] setObject:bookmarkCollection forKey: @"bookmarks"];

    [[NSUserDefaults standardUserDefaults] synchronize];


+ (void)uploadBookmark:(NSDictionary *)singleBookmark 

    NSMutableArray *bookmarkCollection = [[NSUserDefaults standardUserDefaults] objectForKey: @"bookmarks"];


if (!bookmarkCollection) 

    bookmarkCollection = [[NSMutableArray alloc] init];
 

NSMutableDictionary *bookmark1 = [[NSMutableDictionary alloc] initWithDictionary: singleBookmark];

NSMutableDictionary *bookmark2 = [[NSMutableDictionary alloc] initWithDictionary: singleBookmark];


NSNumber *number1 = [[NSNumber alloc] initWithInt: 1];
NSNumber *number2 = [[NSNumber alloc] initWithInt: 2];

[bookmark1 setObject:number1 forKey: @"bookmarkTag"];
[bookmark2 setObject:number2 forKey: @"bookmarkTag"];

[bookmarkCollection addObject: bookmark1];
[bookmarkCollection addObject: bookmark2];

[[NSUserDefaults standardUserDefaults] setObject:bookmarkCollection forKey: @"bookmarks"];

[[NSUserDefaults standardUserDefaults] synchronize];


书签集合是一个可变数组,由具有名称和日期对象/键的字典填充。这些名称和日期是填充另一个视图控制器中表格视图单元格标题的内容。表格视图中的单元格数量由[[BookmarkHandler bookmarkCollection] count];决定

在另一个视图控制器中,您可以删除表格视图单元格,所以我要做的是实现委托方法:

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


if (editingStyle == UITableViewCellEditingStyleDelete) 

    [BookmarkHandler deleteBookmark: indexPath]; 

    [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject: indexPath] withRowAnimation:UITableViewRowAnimationLeft];


所以,当我删除一个单元格时,我通过调用deleteBookmark:BookmarkHandler 中删除一个书签,并从表视图中删除该行。但有时这一行会出现崩溃:

        [bookmarkCollection removeObjectAtIndex: indexPath.row];

但是没有崩溃日志,而且我添加了一个 All Exceptions 断点。

我做错了什么吗?感谢您的帮助...

【问题讨论】:

当您越过断点时,调试器会告诉您什么? @geraldWilliam 什么都没有!真的很奇怪…… 请注意,Xcode 4/ios 5 中存在一个错误,即它不能在所有情况下可靠地产生异常回溯。见this thread。 谢谢@HotLicks btw 这不是一个论坛,所以线程是错误的术语:) 【参考方案1】:

问题出在这里:

NSMutableArray *bookmarkCollection = [[NSUserDefaults standardUserDefaults] objectForKey: @"bookmarks"];

NSUserDefaults 不保存可变数组,它只是将其保存为 NSArray。 所以获取它的可变副本:

NSMutableArray *bookmarkCollection = [[[NSUserDefaults standardUserDefaults] objectForKey: @"bookmarks"] mutableCopy];

【讨论】:

【参考方案2】:

您应该检查 indexPath.row 以确保它没有超出边界。在这之后也许你可以找到原因。

if (indexPath.row>=0 && indexPath.row<bookmarkCollection.count) 
    [bookmarkCollection removeObjectAtIndex: indexPath.row];
 else 
    NSLog(@"indexPath.row is out of boundry of bookmarkCellection size: %d", bookmarkCollection.count);

【讨论】:

我放了那个 if 语句,现在我才得到这个崩溃日志: 2012-09-27 09:10:25.829 MileIndex[35555:1d903] *** 由于未捕获的异常“NSInternalInconsistencyException”而终止应用程序,原因:“-[__NSCFArray removeObjectAtIndex:]: 已发送变异方法到不可变对象' 表示我是 NSArray 中的 removeObjectAtIndex:,但它是一个可变数组...如果我不小心将 bookmarkCollection 设置为非可变 nsarray 对象,请检查我的代码 年,如果你真的没有将 bookmarkCollection 设置为一个不可变的 NSArray,只需从 [[NSUserDefaults standardUserDefaults] objectForKey: @"bookmarks"] 新建一个 NSMutableArray 我在任何地方都看不到 NSArray

以上是关于Objective-C NSMutableArray removeObjectAtIndex:崩溃的主要内容,如果未能解决你的问题,请参考以下文章

NSMutablearray 崩溃删除对象

如何在 UIButtons 之间添加间距 [关闭]

在任务之间留出时间 - iOS

使用 swift 从解析的 Json 中提取数据

如何使用来自 json 的 mutablearray 填充我的 tableview

以编程方式从 ARC 中的导航堆栈中删除 viewController