【发布时间】:2012-07-06 20:01:43
【问题描述】:
我有一个按字母顺序划分的表格视图。我有一个NSMutableArray *drinks,这是我的原始数据源,其中填充了来自 plist 的NSMutableDictionary's。在我的viewDidLoad 方法中。然后,我遍历我的数组并在我的 viewWillAppear 方法中创建部分的键和每个部分中的行数
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
self.sections = [[NSMutableDictionary alloc] init];
BOOL found;
// Loop through the whiskys and create our keys
for (NSMutableDictionary *whisky in self.drinks)
{
NSString *c = [[whisky objectForKey:NAME_KEY] substringToIndex:1];
found = NO;
for (NSString *str in [self.sections allKeys])
{
if ([str isEqualToString:c])
{
found = YES;
}
}
if (!found)
{
[self.sections setValue:[[NSMutableArray alloc] init] forKey:c];
}
}
// Loop again and sort the whiskys into their respective keys
for (NSDictionary *whisky in self.drinks)
{
[[self.sections objectForKey:[[whisky objectForKey:NAME_KEY] substringToIndex:1]] addObject:whisky];
}
// Sort each section array
for (NSString *key in [self.sections allKeys])
{
[[self.sections objectForKey:key] sortUsingDescriptors:[NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:NAME_KEY ascending:YES]]];
}
[self.tableView reloadData];
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view
NSArray *searchPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [searchPaths lastObject];
NSString *writeableDBPath = [documentsDirectory stringByAppendingPathComponent:@"ScotchList.plist"];
NSMutableArray *tmpArray = [[NSMutableArray alloc]initWithContentsOfFile:writeableDBPath];
self.drinks = tmpArray;
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(applicationDidEnterBackground:)
name:UIApplicationDidEnterBackgroundNotification
object:nil];
//Register for application exiting information so we can save data
[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(applicationWillTerminate:) name:UIApplicationWillTerminateNotification object:nil];
}
所有这些都很好用。然后,当我删除一行时,它也可以正常工作。但是,当我转到新视图并返回 tableview 时,已删除的行会重新出现。所以我需要更新我的原始数据源(饮料),因为每次 viewAppears 它都会再次从原始数据源中提取。所以我试图在行中获取项目(威士忌)并将其从数组中删除。但它会抛出一个 sigabrt。这是我的删除行方法。
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete) {
//DELETE THE ROW FROM THE DATA SOURCE
[self.tableView beginUpdates];
[[self.sections valueForKey:[[[self.sections allKeys] sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)] objectAtIndex:indexPath.section]] removeObjectAtIndex:indexPath.row];
NSDictionary *whisky = [[self.sections valueForKey:[[[self.sections allKeys] sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)] objectAtIndex:indexPath.section]] objectAtIndex:indexPath.row];
[self.drinks removeObject:whisky];
if ([[self.sections valueForKey:[[[self.sections allKeys] sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)] objectAtIndex:indexPath.section]] count] > 0)
{
// Section is not yet empty, so delete only the current row.
[tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
else
{
// Section is now completely empty, so delete the entire section.
[self.sections removeObjectForKey:[[[self.sections allKeys] sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)] objectAtIndex:indexPath.section]];
[tableView deleteSections:[NSIndexSet indexSetWithIndex:indexPath.section]
withRowAnimation:UITableViewRowAnimationFade];
}
[self.tableView endUpdates];
} else if (editingStyle == UITableViewCellEditingStyleInsert) {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view.
}
}
这是日志显示的内容:
2012-07-06 15:36:42.454 WhiskyBook[3275:907] *** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayI objectAtIndex:]: index 1 beyond bounds [0 .. 0]'
*** First throw call stack:
(0x3998a17b 0x3494395b 0x398d83bd 0x3e6b5 0x32a0cd11 0x328f0d09 0x328f0cbb 0x328f0c95 0x328f09eb 0x328f1369 0x328ef791 0x328dd72d 0x328dd009 0x339a7603 0x339a7233 0x3995a873 0x3995a817 0x39959611 0x398d6be5 0x398d6a71 0x339a634b 0x329037f5 0x3ac09 0x33cc7b20)
libc++abi.dylib: terminate called throwing an exception
(lldb)
我做错了什么?
【问题讨论】:
-
这是在哪一行调用的?您可以通过输出您正在查看的数组并查看哪个为 nil 来解决此问题。
-
此外,您似乎正在尝试更改不可变数组 - 这就是您的错误包含 __NSArrayI 的原因(I 代表不可变)
-
当我在“tableview commitEditingStyle”方法中放入“NSDictionary *whisky”时,问题就出现了。当我将威士忌输出到日志时,它会以应有的方式显示项目(威士忌)。
-
我找到了解决问题的方法。我没有尝试从 commitEditingStyle 方法内的原始数据源中删除对象,而是为我的 master-viewController 分配了一个 NSDictionary 属性,并在我的 viewDidLoad 中对其进行了初始化,然后为其分配了我想要在其中删除的项目commitEditingStyle 方法。然后在我的 viewWillDisappear 方法中,我将它从原始数据源中删除。
标签: objective-c ios5 uitableview