永远不会调用NSFilePresenter方法

Jon*_*han 5 cocoa objective-c nsfilecoordinator

我正在尝试编写一个简单的(玩具)程序,它使用NSFilePresenter和NSFileCoordinator方法来监视文件的变化.

该程序包含一个文本视图,用于加载(硬编码)文本文件和一个按钮,该文件将保存文件并进行任何更改.我的想法是我有两个实例正在运行,并且在一个实例中保存将导致另一个实例重新加载已更改的文件.

加载和保存文件工作正常,但从不调用NSFilePresenter方法.它都基于一个名为FileManager的类,它实现了NSFilePresenter协议.代码如下:

接口:

@interface FileManager : NSObject <NSFilePresenter>
@property (unsafe_unretained) IBOutlet NSTextView *textView;

- (void) saveFile;
- (void) reloadFile;

@end
Run Code Online (Sandbox Code Playgroud)

执行:

@implementation FileManager
{
    NSOperationQueue* queue;
    NSURL* fileURL;
}

- (id) init {
    self = [super init];
    if (self) {
        self->queue = [NSOperationQueue new];
        self->fileURL = [NSURL URLWithString:@"/Users/Jonathan/file.txt"];
        [NSFileCoordinator addFilePresenter:self];
    }
    return self;
}

- (NSURL*) presentedItemURL {
    NSLog(@"presentedItemURL");
    return self->fileURL;
}

- (NSOperationQueue*) presentedItemOperationQueue {
    NSLog(@"presentedItemOperationQueue");
    return self->queue;
}

- (void) saveFile {
    NSFileCoordinator* coordinator = [[NSFileCoordinator alloc] initWithFilePresenter:self];
    NSError* error;
    [coordinator coordinateWritingItemAtURL:self->fileURL options:NSFileCoordinatorWritingForMerging error:&error byAccessor:^(NSURL* url) {
        NSString* content = [self.textView string];
        [content writeToFile:[url path] atomically:YES encoding:NSUTF8StringEncoding error:NULL];
    }];
}

- (void) reloadFile {
    NSFileManager* fileManager = [NSFileManager defaultManager];
    NSFileCoordinator* coordinator = [[NSFileCoordinator alloc] initWithFilePresenter:self];
    NSError* error;
    __block NSData* content;
    [coordinator coordinateReadingItemAtURL:self->fileURL options:0 error:&error byAccessor:^(NSURL* url) {
        if ([fileManager fileExistsAtPath:[url path]]) {
            content = [fileManager contentsAtPath:[url path]];
        }
    }];
    dispatch_async(dispatch_get_main_queue(), ^{
        [self.textView setString:[[NSString alloc] initWithData:content encoding:NSUTF8StringEncoding]];
    });
}

// After this I implement *every* method in the NSFilePresenter protocol. Each one
// simply logs its method name (so I can see it has been called) and calls reloadFile
// (not the correct implementation for all of them I know, but good enough for now).

@end
Run Code Online (Sandbox Code Playgroud)

注意,调用reloadFile并在applicationDidFinishLaunching每次单击保存按钮时调用saveFile(通过app delegate).

唯一被调用的NSFilePresenter方法(由日志进行)是presentsItemURL(在程序启动时调用四次并在加载文件时调用四次,单击save时调用三次.在第二次实例中单击save对此没有明显影响第一个例子.

谁能告诉我这里我做错了什么?

jlo*_*g64 5

我在这个问题上挣扎了很长一段时间。对我来说,唯一会被调用的方法是-presentedSubitemDidChangeAtURL:(我正在监视目录而不是文件)。我向 Apple 提出了技术支持问题,他们的回应是这是一个错误,我们现在唯一能做的就是-presentedSubitemDidChangeAtURL:在您监视目录时完成所有操作。不确定监视文件时可以做什么。

我鼓励遇到此问题的任何人提交错误 ( https://bugreport.apple.com ),以鼓励 Apple 尽快修复此问题。