我目前在视图控制器上有一个UITableView,它已经设置好了显示已下载到应用程序文档中的所有文件。所以我决定添加通过同一个表视图删除文件的功能。发生的事情是该文件实际上删除但后来崩溃。调试器指出:Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayI objectAtIndex:]: index 0 beyond bounds for empty array'
以下是删除按钮的代码:
// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
NSError *error;
NSFileManager *fileMgr = [NSFileManager defaultManager];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
filePathsArray = [[NSFileManager defaultManager] subpathsOfDirectoryAtPath:documentsDirectory error:nil];
NSString *currentFileName = [filePathsArray[indexPath.row] lastPathComponent];
NSString *documentsDirectoryPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *filePath = [documentsDirectoryPath stringByAppendingPathComponent:currentFileName];
[fileMgr removeItemAtPath:filePath error:&error];
}
}
表格视图代码:
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [filePathsArray count];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"MainCell"];
if (cell == nil) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"MainCell"];
}
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
filePathsArray = [[NSFileManager defaultManager] subpathsOfDirectoryAtPath:documentsDirectory error:nil];
cell.textLabel.text = [filePathsArray[indexPath.row] lastPathComponent];
return cell;
}
那么是什么导致变量超过?任何帮助,将不胜感激!
答案 0 :(得分:3)
我终于明白了!我忘了从数组中删除对象并重新加载tableview,这是任何想要做同样事情的人的工作代码:
// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
filePathsArray = [[NSFileManager defaultManager] subpathsOfDirectoryAtPath:documentsDirectory error:nil];
NSString *currentFileName = [filePathsArray[indexPath.row] lastPathComponent];
NSString *documentsDirectoryPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *filePath = [documentsDirectoryPath stringByAppendingPathComponent:currentFileName];
NSFileManager *fileMgr = [NSFileManager defaultManager];
[fileMgr removeItemAtPath:filePath error:nil];
[filePathsArray removeObjectAtIndex:indexPath.row];
[tableView reloadData];
}
}
答案 1 :(得分:0)
如果删除文件时发生这种情况,我假设您只使用一个文件进行测试。这意味着当您执行此操作时最有可能发生此问题:
[paths objectAtIndex:0];
在尝试访问路径之前,应该检查路径(或从现在开始访问的任何数组)是否为null。所以这看起来像这样:
if(paths == nil || [paths count] == 0){
//handle the exception by not looking in paths, maybe logging something
}
答案 2 :(得分:0)
首先,假设filePathsArray
是一个实例变量,我不清楚为什么每次调用委托方法时重新初始化它。从我的观点来看,它没有意义。您始终(在包括tableView:numberOfRowsInSection:
的所有方法中)使用NSFileManager
的{{1}}并且根本不使用subpathsOfDirectoryAtPath:error:
,或者缓存filePathsArray
'的结果NSFileManager
中的subpathsOfDirectoryAtPath:error:
,仅在删除文件时更新此ivar。
关于您的例外情况,我认为其根本原因如下:
在filePathsArray
方法中,您在不正确的位置重新初始化tableView:commitEditingStyle:forRowAtIndexPath:
。您应该 删除文件后执行此操作。在下面的示例中,我编写了您当前的代码,但没有考虑我上面关于filePathsArray
的评论(即我使用您当前的代码而没有对此评论进行任何修复)。
filePathsArray