我正在尝试编写一个简单的(玩具)程序,它使用 NSFilePresenter 和 NSFileCoordinator 方法来监视文件的更改。
该程序由一个加载(硬编码)文本文件的文本视图和一个用于保存文件更改的按钮组成。我的想法是,我有两个实例正在运行,并且在一个实例中保存将导致另一个实例重新加载更改的文件。
加载和保存文件工作正常,但从未调用 NSFilePresenter 方法。它全部基于一个名为 FileManager 的类,该类实现了 NSFilePresenter 协议。代码如下:
界面:
@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(当程序启动并加载文件时,该方法被调用四次,在单击“保存”时被调用三次。在第二个实例中单击“保存”对第一个例子。
谁能告诉我我在这里做错了什么?
我在这个问题上挣扎了很长一段时间。对我来说,唯一会被调用的方法是-presentedSubitemDidChangeAtURL:
(我正在监视目录而不是文件)。我向 Apple 提出了技术支持问题,他们的回应是这是一个错误,我们现在唯一能做的就是通过-presentedSubitemDidChangeAtURL:
如果您正在监视目录。不确定监视文件时可以做什么。
我鼓励任何遇到此问题的人提交错误(https://bugreport.apple.com https://bugreport.apple.com)鼓励苹果尽快解决这个问题。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)