在iOS上replaceItemAtURL操作失败但没有错误,而在OSX上正常运行。

17
我正在为一款基于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应该位于被视为临时文件的目录中。我假设这意味着使用NSItemReplacementDirectory作为搜索路径的URLForDirectory:inDomain:appropriateForURL:create:error:返回的目录。
那也不起作用!我最终回退到使用单独的操作实现替换逻辑,但这是非原子和不安全的,所有坏的东西都在那里。
有没有人有运行在iOS上并从调用replaceItemAtURL中返回YES的代码片段,或者实际上将错误信息放入错误指针中的工作代码片段?
非常感谢任何帮助。
编辑-测试代码包含在下面。这在主线程的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

你解决了吗?我也遇到了这个问题。 - Steven Fisher
你的示例代码实际上是有问题的,不像你描述的那样能正常工作。我在运行这段代码(复制/粘贴到Xcode中)时,使用的是运行iOS 4.3.3的iPhone;在调用URLForDirectory:etc:之后,tmpDir的值为nil,因此u2也是nil,而调用replaceItemAtURL:etc:导致应用程序崩溃。你到底在做什么?这段代码行不通。 - Tom Harrington
我很兴奋地发现了这个问题,但很遗憾看到没有人给出任何答案。我遇到了完全相同的问题:该方法返回NO,但没有设置错误来告诉我为什么它不起作用。唉! - Sixten Otto
1
我已经在iOS 6上运行了这段代码,它可以正常工作(返回YES)。因此,这可能是自iOS 4以来已经解决的一个错误。 - Drew
rename() 函数有什么问题吗? - tc.
显示剩余6条评论
2个回答

1

我在iOS上使用URL时,所有NSFileManager方法都遇到了问题。然而,使用路径的所有方法都可以正常工作。因此,我认为你应该使用removeItemAtPath:error:copyItemAtPath:toURL:error:来实现这个目的。

希望能对你有所帮助。


-1
在 Mac 文件系统中,大小写不敏感,但在 iOS 中是敏感的。即使您不能在同一位置拥有两个具有相同名称但大小写不同的文件,路径也是大小写敏感的。因此,如果文件名为 .JPEG,并且在您的代码中传递的链接为 .jpeg,则会失败。
这可能不是您的情况,但只是想分享一下。尽管奇怪,它应该会给您一个错误提示。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接