iPhone (iOS): копирование файлов от основного пакета до папки документов вызывает катастрофический отказ

Я пытаюсь настроить свое приложение так, чтобы на первом запуске, серия файлов, расположенных в папке "Populator" в основном пакете, была скопирована в каталог документов.

Моя текущая реализация следующие:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

  NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
  NSString *sourcePath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"Populator"];
  NSString *folderPath = [documentsDirectory stringByAppendingPathComponent:@"Files"];
  NSLog(@"Source Path: %@\n Documents Path: %@ \n Folder Path: %@", sourcePath, documentsDirectory, folderPath);

  NSError *error;

  [[NSFileManager defaultManager] copyItemAtPath:sourcePath 
                                        toPath:folderPath
                                         error:&error];

  NSLog(@"Error description-%@ \n", [error localizedDescription]);
  NSLog(@"Error reason-%@", [error localizedFailureReason]);
  ....
  return YES;
}

Однако это отказывает в первый раз, когда это выполняется со следующими консольными сообщениями (но файлы копируются). В следующий раз, когда приложение открыто, оно не отказывает.

    2010-07-13 15:14:26.418 AppName[5201:207] Source Path: /Users/jack/Library/Application Support/iPhone Simulator/3.2/Applications/1076C1FA-60B0-4AC7-8CD4-74F81472DAE6/AppName.app/Populator
 Documents Path: /Users/jack/Library/Application Support/iPhone Simulator/3.2/Applications/1076C1FA-60B0-4AC7-8CD4-74F81472DAE6/Documents 
 Folder Path: /Users/jack/Library/Application Support/iPhone Simulator/3.2/Applications/1076C1FA-60B0-4AC7-8CD4-74F81472DAE6/Documents/Files
2010-07-13 15:14:26.466 AppName[5201:207] *** +[AppNameAppDelegate localizedDescription]: unrecognized selector sent to class 0xa79c
2010-07-13 15:14:26.475 AppName[5201:207] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** +[AppNameAppDelegate localizedDescription]: unrecognized selector sent to class 0xa79c'
2010-07-13 15:14:26.495 AppName[5201:207] Stack: (
    40911435,
    2569270537,
    41183227,
    40645910,
    40642578,
    9142,
    2815466,
    2819475,
    2844680,
    2826401,
    2858055,
    49271164,
    40452156,
    40448072,
    2817668,
    2850273,
    8776,
    8630
)

У кого-либо есть какие-либо предложения относительно того, что идет не так, как надо? Я уже имею некоторый кодовый набор для реализации "только на первом запуске" функциональность, но не включал его здесь для ясности.

Спасибо

15
задан Jack 13 July 2010 в 14:24
поделиться

4 ответа

Я не очень много знаю о программировании iPhone или objective C, но из любопытства, что является ошибкой в этом случае, если операция копирования действительно удалась? Может быть, это строки журнала, которые сбиваются, если ошибки не было?

[edit] Кроме того, можно ли копировать все содержимое подкаталога подобным образом? (Опять же, я не знаком с iOS API, просто определяю возможные источники ошибок на основе того, что я знаю о других языках/API)

4
ответ дан 1 December 2019 в 02:01
поделиться
   NSError *error;

Вы объявляете локальную переменную без ее инициализации. Поэтому она будет заполнена мусором.

  [[NSFileManager defaultManager] copyItemAtPath:sourcePath 
                                        toPath:folderPath
                                         error:&error];

Если в этой строке не произойдет ошибки, то статус мусора error все равно останется.

  NSLog(@"Error description-%@ \n", [error localizedDescription]);

Теперь вы посылаете сообщение в какое-то случайное, неинициализированное место. Это и есть источник сбоя.


Чтобы избежать этого, инициализируйте error в nil.

NSError* error = nil;
//             ^^^^^

Или выводите ошибку только тогда, когда -copyItemAtPath:... возвращает NO (при этом error корректно заполняется).

if (![[NSFileManager defaultManager] copyItemAtPath:sourcePath ...]) {
  NSLog(...); 
}
15
ответ дан 1 December 2019 в 02:01
поделиться

Я только что прочитал свой код и обнаружил проблему. Как Шон Эдвардс указывает выше, в случае успеха ошибки не возникает - отсюда и сбой.

Вот мой новый код для интересующихся:

if([[NSFileManager defaultManager] copyItemAtPath:sourcePath toPath:folderPath error:&error]){
    NSLog(@"File successfully copied");
} else {
    NSLog(@"Error description-%@ \n", [error localizedDescription]);
    NSLog(@"Error reason-%@", [error localizedFailureReason]);
}
5
ответ дан 1 December 2019 в 02:01
поделиться

Вы регистрируете ошибку до того, как узнаете, что она есть

поместите код в if-блок

if(error)
{
 NSLog(@"Error description-%@ \n", [error localizedDescription]);
 NSLog(@"Error reason-%@", [error localizedFailureReason]);
}

Чтобы описать вашу проблему более подробно: указатель ошибки указывает на ЛЮБОЕ место, и этот объект не распознает это сообщение. Поэтому вы получаете исключение

2
ответ дан 1 December 2019 в 02:01
поделиться
Другие вопросы по тегам:

Похожие вопросы: