0

我有一个编写包样式文档的工具。它使用 NSDocument 实现并覆盖以下 NSDocument 方法:

- (NSFileWrapper *)fileWrapperOfType:(NSString *)typeName
                              error:(NSError **)outError;

- (BOOL)readFromFileWrapper:(NSFileWrapper *)fileWrapper
                    ofType:(NSString *)typeName
                     error:(NSError **)outError;

这一切都很可爱,除非我保存了一个受版本控制的文档。(不保留 .svn 目录等)

有没有什么好方法可以让我的文档在 svn 上运行良好?

4

2 回答 2

3

我猜您的代码通过每次-fileWrapperOfType:error:调用时创建一个新的文件包装器来工作。这很方便,但会忽略包内磁盘上可能存在的任何其他文件。

因此,如果您从创建/使用引用磁盘上现有内容的文件包装器开始,该怎么办。修改该包装器以匹配文档的当前状态,并返回结果。当该包装器被写入磁盘时,应该正确维护 svn 文件。

于 2010-08-24T22:56:33.507 回答
1

这是我基于迈克回答的解决方案!

我的文档包是捆绑包,具有通常的层次结构……因此,我在保存期间更改了四个目录:

  1. 保存创建一个新的顶级(My.bundle)
  2. 内容目录已更改 (My.bundle/Contents)
  3. 资源目录已更改 (My.bundle/Contents/Resources)
  4. 本地化资源已更新 (My.bundle/Contents/Resources/en.lproj)

该配方首先向您的文档类添加一个可变字典槽,以保留每个目录的内容。

@interface LMDocument : NSDocument {
@private
    // All this is for preserving SCM artifacts across saves…
    NSMutableDictionary * bundleWrappers;
    NSMutableDictionary * contentsWrappers;
    NSMutableDictionary * resourcesWrappers;
    NSMutableDictionary * localizedWrappers;
}

当创建一个新文档时,这些开始是空字典。

- (id)init;
{
    if ((self = [super init]) != nil) {
        bundleWrappers = [[NSMutableDictionary alloc] initWithCapacity:0];
        contentsWrappers = [[NSMutableDictionary alloc] initWithCapacity:0];
        resourcesWrappers = [[NSMutableDictionary alloc] initWithCapacity:0];
        localizedWrappers = [[NSMutableDictionary alloc] initWithCapacity:0];
    }
    return self;
}

在读取现有文档时,将这些替换为相关 fileWrapper 内容的可变副本。

- (BOOL)readFromFileWrapper:(NSFileWrapper *)fileWrapper
                     ofType:(NSString *)typeName
                      error:(NSError **)outError;
{
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
    bundleWrappers = [[fileWrapper fileWrappers] mutableCopy];
    contentsWrappers = [[[bundleWrappers objectForKey:@"Contents"] fileWrappers] mutableCopy];
    resourcesWrappers = [[[contentsWrappers objectForKey:@"Resources"] fileWrappers] mutableCopy];
    localizedWrappers = [[[resourcesWrappers objectForKey:@"en.lproj"] fileWrappers] mutableCopy];
    NSFileWrapper * infoPlistWrapper = [contentsWrappers objectForKey:@"Info.plist"];
    [contentsWrappers removeObjectForKey:@"Info.plist"]; // Replaced during save…
    // …
    NSMutableDictionary * localizedWrappersCopy = [localizedWrappers mutableCopy];
    [localizedWrappers enumerateKeysAndObjectsUsingBlock:^(id key,
                                                           id obj,
                                                           BOOL * stop)
     {
         if (mumble) { // If it's a file that will be replaced during save…
             [localizedWrappersCopy removeObjectForKey:key]; // Replaced during save…
             // …
         }
     }];
    localizedWrappers = localizedWrappersCopy;
    [pool drain];
    return YES;
}

最后,在保存文档时使用精心准备的字典。

- (NSFileWrapper *)fileWrapperOfType:(NSString *)typeName
                               error:(NSError **)outError;
{
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
    NSFileWrapper * localizedWrapper =
    [[NSFileWrapper alloc] initDirectoryWithFileWrappers:localizedWrappers];
    [resourcesWrappers setObject:localizedWrapper
                          forKey:@"en.lproj"];
    NSFileWrapper * resourcesWrapper =
    [[NSFileWrapper alloc] initDirectoryWithFileWrappers:resourcesWrappers];
    [contentsWrappers setObject:resourcesWrapper
                         forKey:@"Resources"];
    NSFileWrapper * contentsWrapper =
    [[NSFileWrapper alloc] initDirectoryWithFileWrappers:contentsWrappers];
    // …
    for (id item in mumble) {
        NSString * filename = [item filename];
        NSData * data = [item data];
        [localizedWrapper addRegularFileWithContents:data
                                   preferredFilename:filename];
    }
    [contentsWrapper addRegularFileWithContents:[self infoPlistData]
                              preferredFilename:@"Info.plist"];
    [pool drain];
    [bundleWrappers setObject:contentsWrapper
                       forKey:@"Contents"];
    NSFileWrapper * bundleWrapper =
    [[[NSFileWrapper alloc] initDirectoryWithFileWrappers:bundleWrappers] autorelease];
    return bundleWrapper;
}

现在,当编辑包文档时,应用程序会保留它没有添加到包中的所有文件,包括 SCM 工件和“其他”本地化!

于 2010-08-25T01:09:27.973 回答