我在我的应用程序的Documents目录中有一个kQueue观察者.我正在使用kQueue,当Documents目录内容发生变化时触发回调.
这是两个设置
eventToAdd.flags = EV_ADD | EV_CLEAR;
eventToAdd.fflags = NOTE_WRITE;
问题是当添加新文件时内容发生变化时我收到通知,但实际文件尚未完全复制,因此当我尝试处理新文件时,我收到SIGABRT崩溃.
如何在文件完成之前延迟通知?
最佳答案 我通过创建2个侦听器来解决这个问题…一个在应用程序的Documents目录中,用于监视出现的新文件,以及为出现的每个文件创建的File代理对象. File对象有一个fileBusy标志.当一块数据写入文件时,File对象设置一个2秒的计时器.我假设如果在计时器到期之前没有更新,则完全写入文件.
文件更改侦听器代码在这里:https://gist.github.com/nielsbot/5155671
我的(部分)代表以下听众. (表示磁盘上文件的“File”对象)
@implementation File<FileChangeObserverDelegate>
-(void)scheduleFileBusyTimeout
{
self.fileBusyTimeoutTimer = [ NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector( fileBusyTimeoutTimerFired: ) userInfo:nil repeats:NO ] ;
}
-(void)setFileChangeObserver:(FileChangeObserver *)observer
{
[_fileChangeObserver invalidate ] ;
_fileChangeObserver = observer ;
}
-(void)fileChanged:(FileChangeObserver *)asset typeMask:(enum FileChangeNotificationType)type
{
@synchronized( self )
{
if ( ( type & kFileChangeType_Delete ) != 0 )
{
// we're going away soon...
self.fileChangeObserver = nil ;
}
else
{
self.fileBusy = YES ;
[ self scheduleFileBusyTimeout ] ;
}
}
}
-(void)fileBusyTimeoutTimerFired:(NSTimer*)timer
{
@autoreleasepool {
self.fileBusy = NO ;
}
}
-(void)setFileBusyTimeoutTimer:(NSTimer *)timer
{
[ _fileBusyTimeoutTimer invalidate ] ;
_fileBusyTimeoutTimer = timer ;
}
@end