-1

我有一些代码在我的uitableview. 但是,一旦删除文件并刷新我就会收到错误消息。这是显示文件名、删除按钮操作和错误的代码:

首先,当按下按钮时,我运行此代码,该代码在将文件添加到表时有效:

-(IBAction)refresh{

    [[self mytable] reloadData];
}

其次,我有这段代码来获取和显示表格要显示的值。这工作正常,直到发生删除和更新:

- (void)viewDidLoad
{
    [super viewDidLoad];

    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    filePathsArray = [[[NSFileManager defaultManager] subpathsOfDirectoryAtPath:documentsDirectory  error:nil]mutableCopy];


    mytable.dataSource = self;
    mytable.delegate = self;



}

-

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
    if(!filePathsArray)
    {
        return 0;
    }
    if ([filePathsArray count] > 0)
        return [filePathsArray count];
    else
        return 0;


}

-

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
    if (editingStyle == UITableViewCellEditingStyleDelete) {
        //add code here for when you hit delete
        NSString *currentFileName = filePathsArray[indexPath.row];
        NSString *documentsDirectoryPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask,YES) objectAtIndex:0];
        NSString *filePath = [documentsDirectoryPath stringByAppendingPathComponent:currentFileName];
        fileURL = [NSURL fileURLWithPath:filePath];
        NSLog(@"urlstring %@",fileURL);
        NSFileManager *fileManager = [NSFileManager defaultManager];
        [fileManager removeItemAtPath:filePath error:NULL];
        NSLog(@"successfully deleted");

    }
}

-

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"MainCell"];
    if (cell == nil) {
        cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"MainCell"];
    }


    NSLog(@"urlstring %@",[filePathsArray objectAtIndex:indexPath.row]);


    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];
filePathsArray = [[NSArray alloc] initWithArray: [[[NSFileManager defaultManager] subpathsOfDirectoryAtPath:documentsDirectory error:nil]mutableCopy]];
    return cell;
}

-

-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
    return 1;

}

我收到的错误是这样的:

 *** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayI objectAtIndex:]: index 6 beyond bounds [0 .. 5]'
*** First throw call stack:
(0x2049012 0x1473e7e 0x1ffeb44 0x3c3a 0x69b8fb 0x69b9cf 0x6841bb 0x694b4b 0x6312dd 0x14876b0 0x2c84fc0 0x2c7933c 0x2c79150 0x2bf70bc 0x2bf8227 0x2bf88e2 0x2011afe 0x2011a3d 0x1fef7c2 0x1feef44 0x1feee1b 0x23dc7e3 0x23dc668 0x5e0ffc 0x2212 0x2145)
libc++abi.dylib: terminate called throwing an exception
(lldb) 

由于以下原因,我收到此错误:

NSLog(@"urlstring %@",[filePathsArray objectAtIndex:indexPath.row]);

但是一旦删除它就说问题出在下一行。有人可以帮忙吗?

4

2 回答 2

2

由于您在 filePathsArray 中设置数据的方式,您的 tableView 渲染的单元格比需要的多一个。

删除文件后,更新 filePathsArray。

发生的情况是,在您的commitEditingStyle方法中您删除了一个文件,但您没有更新 filePathsArray 对象以删除该文件的子路径。

更新 filePathsArray 的唯一地方是在之后cellForRowAtIndexPath调用 numberOfRowsInSection

所以基本上:

  1. 例如,您的 filePathsArray 包含 6 个文件的子路径。
  2. 您删除了一个文件,commitEditingStyle但没有更新 filePathsArray(它仍然包含 6 个子路径)。
  3. 你按下按钮reloadData
  4. numberOfRowsInSection调用以获取要在 UITableView 上显示的单元格数...这将返回 [filePathsArray count] 仍然为 6。
  5. cellForRowAtIndexPath现在为每一行调用。
  6. 在上面的方法中,您filePathsArray = [[NSFileManager defaultManager] subpathsOfDirectoryAtPath:documentsDirectory error:nil];现在调用 filePathsArray 有 5 个对象,因为已删除文件。
  7. 但你猜怎么着......你的 UITableView 已经开始为旧的 filePathsArray 计数渲染 6 行。
  8. 现在,当它呈现单元格编号 6 (indexPath.row = 5) 时,它会调用cell.textLabel.text = [filePathsArray[indexPath.row] lastPathComponent];并且数组的最后一个索引现在是 4。这会导致崩溃。

只需执行filePathsArray = [[NSFileManager defaultManager] subpathsOfDirectoryAtPath:documentsDirectory error:nil];commitEditingStyle的操作,错误就会停止。

另外,尽量不要在cellForRowAtIndexPath. filePathsArray = [[NSFileManager defaultManager] subpathsOfDirectoryAtPath:documentsDirectory error:nil];由于您的数组现在正在更新中,因此请从那里进行调用commitEditingStyle

于 2013-07-10T18:51:10.167 回答
1

tableView:cellForRowAtIndexPath:中,删除此代码:filePathsArray = [[NSFileManager defaultManager] subpathsOfDirectoryAtPath:documentsDirectory error:nil];

tableView:commitEditingStyle:中,添加以下代码:

[filePathsArray removeObjectAtIndex:indexPath.row];

这应该保持您用于填充表格视图的数据的完整性(因此当表格不知道时您不会更改项目数,并且当表格认为您有时您会更改它)。

于 2013-07-10T18:46:10.643 回答