NSFilePresenter メソッドと NSFileCoordinator メソッドを使用してファイルの変更を監視する単純な (おもちゃの) プログラムを作成しようとしています。
このプログラムは、(ハードコードされた) テキスト ファイルをロードするテキスト ビューと、ファイルに変更を加えて保存するボタンで構成されます。アイデアは、2 つのインスタンスを実行していて、1 つのインスタンスに保存すると、他のインスタンスが変更されたファイルをリロードするというものです。
ファイルの読み込みと保存は正常に機能しますが、NSFilePresenter メソッドは呼び出されません。これはすべて、NSFilePresenter プロトコルを実装する FileManager というクラスに基づいています。コードは次のとおりです。
インターフェース:
@interface FileManager : NSObject <NSFilePresenter>
@property (unsafe_unretained) IBOutlet NSTextView *textView;
- (void) saveFile;
- (void) reloadFile;
@end
実装:
@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
reloadFile が呼び出されapplicationDidFinishLaunching
、保存ボタンがクリックされるたびに saveFile が呼び出されることに注意してください (アプリ デリゲートを介して)。
これまでに呼び出される唯一の NSFilePresenter メソッド (ログによる) はpresentedItemURL です (プログラムが起動してファイルをロードするときに 4 回呼び出され、保存がクリックされるたびに 3 回呼び出されます。2 番目のインスタンスで [保存] をクリックしても、最初のインスタンス。
ここで私が間違っていることを誰かに教えてもらえますか?