Chr*_*men 6 cocoa bundle nsdocument
所以在谷歌搜索后,我的理解是,当我在基于NSDocument的应用程序中使用捆绑包作为我的文档时,我必须在每次要保存时编写整个捆绑包?由于我正在向文档中添加大量视频文件,因此这开始出现问题.
有没有办法解决这个问题而不抛弃NSDocument?
小智 11
使用文档包的一个优点是每次保存时都不需要编写所有内容.您应该documentFileWrapper向NSDocument子类添加属性,并且当文档体系结构读入文档包时,您应该NSFileWrapper在该属性中存储引用,并且还应该跟踪已更改的内容.例如,aAssuming您在文档包中保留了文本文件和视频文件:
@interface MyDocument ()
@property (nonatomic, copy) NSString *text;
@property (nonatomic, assign) bool textHasChanged;
@property (nonatomic, copy) NSData *videoData;
@property (nonatomic, assign) bool videoHasChanged;
@property (nonatomic, strong) NSFileWrapper *documentFileWrapper;
@end
Run Code Online (Sandbox Code Playgroud)
和
- (BOOL)readFromFileWrapper:(NSFileWrapper *)fileWrapper
ofType:(NSString *)typeName
error:(NSError **)outError {
// Read the contents of file wrapper
// …
[self setDocumentFileWrapper:fileWrapper];
return YES;
}
Run Code Online (Sandbox Code Playgroud)
如果从磁盘读取文档包,则documentFileWrapper保留对该包的引用.如果它是一个新文件,documentFileWrapper是nil.
保存文档时,您documentFileWrapper只能重复使用并只写入需要保存的文件.如果文档尚未保存(这是一个新文档),documentFileWrapper是nil,所以你需要创建一个:
- (NSFileWrapper *)fileWrapperOfType:(NSString *)typeName
error:(NSError **)outError
{
if ([self documentFileWrapper] == nil) {
NSFileWrapper *documentFileWrapper = [[NSFileWrapper alloc] initDirectoryWithFileWrappers:@{}];
[self setDocumentFileWrapper:documentFileWrapper];
}
NSDictionary *fileWrappers = [[self documentFileWrapper] fileWrappers];
NSFileWrapper *textFileWrapper = [fileWrappers objectForKey:@"text.txt"];
NSFileWrapper *videoFileWrapper = [fileWrappers objectForKey:@"video.mp4"];
if ((textFileWrapper == nil && [self text] != nil) || [self textHasChanged]) {
if (textFileWrapper != nil)
[documentFileWrapper removeFileWrapper:textFileWrapper];
if ([self text] != nil) {
NSData *textData = [[self text] dataUsingEncoding:NSUTF8StringEncoding];
[documentFileWrapper addRegularFileWithContents:textData preferredFileName:@"text.txt"];
}
}
if ((videoFileWrapper == nil && [self videoData] != nil) || [self videoHasChanged]) {
if (videoFileWrapper != nil)
[documentFileWrapper removeFileWrapper:videoFileWrapper];
if ([self videoData] != nil)
[documentFileWrapper addRegularFileWithContents:[self videoData] preferredFileName:@"video.mp4"];
}
return documentFileWrapper;
}
Run Code Online (Sandbox Code Playgroud)
在上面的代码中,仅当文档包(文件包装器)尚不存在时才会创建它.换句话说,仅当文档是新文档且尚未保存时才会创建它.创建包后,其引用存储在documentFileWrapper.
接下来,我们检查是否需要编写文本文件.它是在以下情况下编写的:*要么还没有文本文件(可能因为它是一个新的包)而且我们有实际的文本要写;*或文本是否已更改.
我们对视频文件也这样做.
请注意,如果文档已从磁盘加载或至少保存一次,则仅当视频数据已更改时,视频文件才会添加到包中(如果有的话,还会从包中删除以前的视频文件).
注意:这个答案假定ARC和自动属性合成(ivar名称前缀为下划线).