首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >NSFilePresenter方法从不被调用

NSFilePresenter方法从不被调用
EN

Stack Overflow用户
提问于 2013-03-28 06:26:50
回答 2查看 2.4K关注 0票数 6

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

该程序由一个文本视图和一个按钮组成,该视图加载一个(硬编码)文本文件,该按钮将保存包含任何更改的文件。这个想法是,我有两个实例在运行,保存在一个实例中将导致另一个实例重新加载更改后的文件。

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

接口:

代码语言:javascript
复制
@interface FileManager : NSObject <NSFilePresenter>
@property (unsafe_unretained) IBOutlet NSTextView *textView;

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

@end

实施:

代码语言:javascript
复制
@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

请注意,在applicationDidFinishLaunching中调用reloadFile,并且每次单击保存按钮时都会调用saveFile (通过应用程序委托)。

惟一被调用的NSFilePresenter方法(根据日志)是presentedItemURL (在程序启动和加载文件时调用四次,每次单击保存时调用三次。在第二个实例中单击保存对第一个实例没有明显影响。

有人能告诉我我哪里做错了吗?

EN

回答 2

Stack Overflow用户

发布于 2013-10-13 17:47:30

我在这个问题上挣扎了很长一段时间。对我来说,唯一要调用的方法是-presentedSubitemDidChangeAtURL: (我监视的是目录而不是文件)。我向苹果公司提出了一个技术支持问题,他们的反应是这是一个bug,如果你在监控一个目录,我们现在唯一能做的就是通过-presentedSubitemDidChangeAtURL:来做所有的事情。不确定在监视文件时可以做些什么。

我鼓励任何遇到这个问题的人提交一个bug (https://bugreport.apple.com),以鼓励苹果尽快解决这个问题。

票数 4
EN

Stack Overflow用户

发布于 2016-06-16 04:29:51

(我知道这是一个老问题,但是...:)

首先,我注意到你没有[NSFileCoordinator removeFilePresenter:self]; anywhere (它应该在dealloc中)。

其次,你写道:

代码语言:javascript
复制
    // 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).

你是对的:这是错误的实现!你错了:这还不够好,因为对于像accommodatePresentedItemDeletionWithCompletionHandler:这样接受完成块作为参数的方法来说,当你实现它们时,实际上调用这个完成块是必不可少的,例如

代码语言:javascript
复制
    - (void) savePresentedItemChangesWithCompletionHandler:(void (^)(NSError * _Nullable))completionHandler
    {
        // implement your save routine here, but only if you need to!
        if ( dataHasChanged ) [self save]; // <-- meta code
        //
        NSError * err = nil; // <-- = no error, in this simple implementation
        completionHandler(err); // <-- essential!
    }

我不知道这是否是您的协议方法不被调用的原因,但这肯定是一个开始。好吧,假设你还没有找出过去三年的问题所在!:-)

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15670720

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档