通过UITableView删除本地文件导致越界数组

时间:2014-06-22 01:23:36

标签: ios objective-c uitableview

我目前在视图控制器上有一个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;
}

那么是什么导致变量超过?任何帮助,将不胜感激!

3 个答案:

答案 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