2013-07-10 2 views
-1

У меня есть код, отображающий имя файла в моем uitableview. однако после удаления файла и обновления я получаю сообщение об ошибке. Вот мой код, чтобы отобразить мое имя файла, мои удалить действия кнопки и ошибка:Objective-C: Как обновить 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

Мне нравится реализация 'numberOfRowsInSection:'. Вместо 'return filePathsArray.count;' вы делаете две лишние и избыточные проверки (приводя к 3 ненужным путям выполнения), которые не защищают вас от чего-либо, только уменьшают удобочитаемость и путают того, кто пытается прорыть код. –

+2

@ H2CO3 Я «люблю», как вам удается превращать разумные советы в депрессивные комментарии. – herzbube

+1

@herzbube Мне тоже нравится это. Это особая сила. –

ответ

2

Из-за того, как вы устанавливаете данные в файлеPathsArray, ваш tableView рендерит одну дополнительную ячейку больше, чем необходимо.

После удаления файла обновите файл FilePathsArray.

Что происходит, так это то, что в вашем методе commitEditingStyle вы удаляете файл, но вы не обновляете объект filePathsArray, чтобы удалить подпуть для этого файла.

Единственное место, где вы обновляете filePathsArray в cellForRowAtIndexPath, который называется послеnumberOfRowsInSection

Так в основном:

  1. Э.Г. ваш файлPathsArray содержит подпапки для 6 файлов.
  2. Вы удаляете файл в commitEditingStyle, но вы не обновляете filePathsArray (который по-прежнему содержит 6 подпапок).
  3. Вы нажимаете кнопку на reloadData
  4. numberOfRowsInSection называется, чтобы получить число ячеек, которые будут отображаться на UITableView ... Это возвращает [filePathsArray Count], которая по-прежнему 6.
  5. cellForRowAtIndexPath теперь называется для каждого ряд.
  6. Внутри вышеуказанного метода вы вызываете filePathsArray = [[NSFileManager defaultManager] subpathsOfDirectoryAtPath:documentsDirectory error:nil];, так что теперь ваш файлPathsArray имеет 5 объектов из-за удаленного файла.
  7. Но угадайте, что .... Ваш UITableView уже начал рендеринг 6 строк для старого счетчика filePathsArray.
  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.

+1

Большое вам спасибо – user2569812

1

В tableView:cellForRowAtIndexPath:, удалить этот код: filePathsArray = [[NSFileManager defaultManager] subpathsOfDirectoryAtPath:documentsDirectory error:nil];

В tableView:commitEditingStyle:, добавьте этот код:

[filePathsArray removeObjectAtIndex:indexPath.row]; 

Это должно поддерживать целостность данных, которые вы используете, чтобы заполнить вид таблицы (так что вы не изменяйте количество элементов, когда таблица не знает об этом, и вы меняете его, когда таблица считает, что у вас есть).

+0

^Согласитесь ... мои мысли точно. – Sid

Смежные вопросы