replaceItemAtURL не работает без ошибок на iOS, но отлично работает на OSX - PullRequest
17 голосов
/ 04 февраля 2011

Я реализую инициированный вручную процесс миграции для приложения на основе CoreData, и после успешного завершения миграции я пытаюсь переместить перенесенную БД обратно поверх исходной, используя replaceItemAtURL:withItemAtURL:backupItemName:options:resultingItemURL:error:.

Проблема в том, что на iOS ничего из того, что я делаю, не заставляет этот метод возвращать YES, однако он также никогда не помещает ничего в указатель ошибки, чтобы вы могли увидеть, что происходит не так.

Я бы прочитал что-нибудь в другом месте (например, http://www.cocoabuilder.com/archive/cocoa/287790-nsdoc-magic-file-watcher-ruins-core-data-migration.html), указывая, что причиной может быть не завершение работы всех объектов CoreData (например, NSMigrationManager, NSManagedObjectModel и т. Д.), Но это не так. даже реализовал две вещи для создания и замены файлов, которые вообще не включали базы данных CoreData, чтобы проверить, что материал CoreData не имеет к этому никакого отношения.

Затем я заметил в официальной документации , что newitemURL должен находиться в каталоге, который считается подходящим для временных файлов. Я предположил, что это означало каталог, возвращаемый URLForDirectory:inDomain:appropriateForURL:create:error: с использованием NSItemReplacementDirectory в качестве пути поиска.

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

Есть ли у кого-нибудь работающий фрагмент кода, работающий на iOS, который либо возвращает YES после вызова replaceItemAtURL, либо фактически помещает информацию об ошибке в указатель ошибки?

Любая помощь высоко ценится.

РЕДАКТИРОВАТЬ - Тестовый код включен ниже. Это выполняется в application:didFinishLaunchingWithOptions: в главном потоке.

NSFileManager *fm = [[NSFileManager alloc] init];
NSError *err = nil;
NSURL *docDir = [NSURL fileURLWithPath:[self applicationDocumentsDirectory]];

NSURL *tmpDir = [fm URLForDirectory:NSItemReplacementDirectory
                           inDomain:NSUserDomainMask
                  appropriateForURL:docDir
                             create:NO
                              error:&err];

NSURL *u1 = [docDir URLByAppendingPathComponent:@"f1"];
NSURL *u2 = [tmpDir URLByAppendingPathComponent:@"f2"];
NSURL *repl = nil;

[fm createFileAtPath:[u1 path]
            contents:[[NSString stringWithString:@"Hello"]
                      dataUsingEncoding:NSUTF8StringEncoding]
          attributes:nil];

[fm createFileAtPath:[u2 path]
            contents:[[NSString stringWithString:@"World"]        
                      dataUsingEncoding:NSUTF8StringEncoding]
          attributes:nil];

BOOL test = [fm replaceItemAtURL:u1 withItemAtURL:u2 backupItemName:@"f1backup"
                         options:0 resultingItemURL:&repl error:&err];

// At this point GDB shows test to be NO but error is still nil

Ответы [ 2 ]

1 голос
/ 07 сентября 2011

У меня возникли проблемы со всеми методами NSFileManager, использующими URL на iOS. Однако все методы, использующие Path, работают. Поэтому я думаю, что вы должны использовать removeItemAtPath:error: и copyItemAtPath:toURL:error: для этой цели.

Надеюсь, это поможет

0 голосов
/ 20 февраля 2013

В файловой системе Mac регистр не учитывается, но в IOS.Даже если у вас не может быть двух файлов с одинаковым именем, но с разным регистром в одном месте, путь чувствителен к регистру.Так что, если файл имеет .JPEG и в вашем коде вы передаете ссылку с .jpeg, это не удастся.Возможно, дело не в тебе, а в том, чем поделиться

Хотя, как ни странно, это должно дать тебе ошибку.

...