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对此没有明显影响第一个例子.
谁能告诉我这里我做错了什么?
我在这个问题上挣扎了很长一段时间。对我来说,唯一会被调用的方法是-presentedSubitemDidChangeAtURL:(我正在监视目录而不是文件)。我向 Apple 提出了技术支持问题,他们的回应是这是一个错误,我们现在唯一能做的就是-presentedSubitemDidChangeAtURL:在您监视目录时完成所有操作。不确定监视文件时可以做什么。
我鼓励遇到此问题的任何人提交错误 ( https://bugreport.apple.com ),以鼓励 Apple 尽快修复此问题。
| 归档时间: |
|
| 查看次数: |
1779 次 |
| 最近记录: |