NSDocument 和 writeToURL:ofType:error 的问题:
Posted
技术标签:
【中文标题】NSDocument 和 writeToURL:ofType:error 的问题:【英文标题】:Problem with NSDocument and writeToURL:ofType:error: 【发布时间】:2009-10-18 05:49:38 【问题描述】:我正在开发基于文档的应用程序,我想使用文档包作为我的文件格式。为此,我需要重写的 NSDocument 方法似乎是-writeToURL:ofType:error:
。
它有时有效,但仅在某些条件下有效。例如,此代码有效:
- (BOOL)writeToURL:(NSURL *)absoluteURL ofType:(NSString *)typeName error:(NSError **)outError
NSFileWrapper *wrapper = [[NSFileWrapper alloc] initDirectoryWithFileWrappers:nil];
[wrapper addRegularFileWithContents:[@"please work" dataUsingEncoding:NSUTF8StringEncoding] preferredFilename:@"foobar"];
[wrapper writeToURL:absoluteURL options:NSFileWrapperWritingAtomic originalContentsURL:nil error:outError];
NSDictionary *metadata = [NSDictionary dictionaryWithObject:@"0.1" forKey:@"Version"];
NSURL *mdURL = [NSURL fileURLWithPath:[[absoluteURL path] stringByAppendingPathComponent:@"SiteInfo.plist"]];
[metadata writeToURL:mdURL atomically:YES];
return YES;
但是,这段代码没有(和上面一样,只是去掉了 NSFileWrapper 位):
- (BOOL)writeToURL:(NSURL *)absoluteURL ofType:(NSString *)typeName error:(NSError **)outError
NSDictionary *metadata = [NSDictionary dictionaryWithObject:@"0.1" forKey:@"Version"];
NSURL *mdURL = [NSURL fileURLWithPath:[[absoluteURL path] stringByAppendingPathComponent:@"SiteInfo.plist"]];
[metadata writeToURL:mdURL atomically:YES];
return YES;
上面的代码将这个神秘的错误放入控制台(“Lithograph”是我的应用程序的名称,“.site”是包扩展名):
NSDocument could not delete the temporary item at file://localhost/private/var/folders/qX/qXL705byGmC9LN8FpiVjgk+++TI/TemporaryItems/(A%20Document%20Being%20Saved%20By%20Lithograph%207)/Untitled%20Site.site. Here's the error:
Error Domain=NSCocoaErrorDomain Code=4 UserInfo=0x10059d160 "“Untitled Site.site” couldn’t be removed."
在将其他文件添加到包之前,我是否必须向原始 URL 写入内容?
【问题讨论】:
【参考方案1】:如果您从文档创建文件包装器,则应使用 -fileWrapperOfType:error:
而不是 -writeToURL:ofType:error:
。
您将为 Info.plist 文件构建一个文件包装器,将其插入到文件夹文件包装器中,然后返回文件夹包装器:
- (NSFileWrapper *)fileWrapperOfType:(NSString *)typeName error:(NSError **)outError
NSFileWrapper *wrapper = [[[NSFileWrapper alloc] initDirectoryWithFileWrappers:nil] autorelease];
[wrapper addRegularFileWithContents:[@"please work" dataUsingEncoding:NSUTF8StringEncoding] preferredFilename:@"foobar"];
NSDictionary *metadata = [NSDictionary dictionaryWithObject:@"0.1" forKey:@"Version"];
NSString* errorDescription = nil;
NSData* dictionaryData = [NSPropertyListSerialization dataFromPropertyList:metadata format:NSPropertyListBinaryFormat_v1_0 errorDescription:&errorDescription];
if(!dictionaryData)
if(!errorDescription)
errorDescription = @"Unknown error";
if(outError)
*outError = [NSError errorWithDomain:@"YourErrorDomain" code:69 userInfo:[NSDictionary dictionaryWithObject:errorDescription forKey:NSLocalizedDescriptionKey]];
return nil;
[wrapper addRegularFileWithContents:dictionaryData preferredFilename:@"Info.plist"];
return wrapper;
【讨论】:
感谢您的帮助!我不知道NSPropertyListSerialization
;这应该会派上用场。【参考方案2】:
我能够解决我自己的问题!通过在方法的顶部添加这行代码,我可以在包中操作我想要的任何文件:
[[NSFileManager defaultManager] createDirectoryAtPath:[absoluteURL path] withIntermediateDirectories:YES attributes:nil error:nil];
【讨论】:
永远不要将nil
传递给error:
。首先,它是指向指针的指针,而不是指向对象的指针,因此正确的空值是NULL
。更重要的是,您正在向用户隐藏错误。如果他们没有写入该位置的权限,那么该消息将尝试为您提供一个错误对象,但您拒绝接收它,因此您无法展示它,因此您的应用将静默保存失败.【参考方案3】:
writeToURL... 方法实现应该始终创建一个完整的文档。你的第二个版本似乎没有这样做,所以我不确定你为什么认为它应该工作。
【讨论】:
以上是关于NSDocument 和 writeToURL:ofType:error 的问题:的主要内容,如果未能解决你的问题,请参考以下文章
NSDocument 和 writeToURL:ofType:error 的问题: