Files
2014-08-08 13:27:54 +08:00

104 lines
1.9 KiB
Objective-C

//
// DTFolderMonitor.m
// DTFoundation
//
// Created by Oliver Drobnik on 05.08.13.
// Copyright (c) 2013 Cocoanetics. All rights reserved.
//
#import "DTFolderMonitor.h"
@implementation DTFolderMonitor
{
NSURL *_URL;
DTFolderMonitorBlock _block;
int _fileDescriptor;
dispatch_queue_t _queue;
dispatch_source_t _source;
}
+ (DTFolderMonitor *)folderMonitorForURL:(NSURL *)URL block:(DTFolderMonitorBlock)block
{
return [[DTFolderMonitor alloc] initWithURL:URL block:block];
}
- (instancetype)initWithURL:(NSURL *)URL block:(DTFolderMonitorBlock)block
{
NSParameterAssert(URL);
NSParameterAssert(block);
NSAssert([URL isFileURL], @"URL Parameter must be a folder URL");
self = [super init];
if (self)
{
_URL = URL;
_block = [block copy];
_queue = dispatch_queue_create("DTFolderMonitor Queue", 0);
}
return self;
}
- (void)dealloc
{
[self stopMonitoring];
#if !OS_OBJECT_USE_OBJC
dispatch_release(_queue);
#endif
}
- (void)startMonitoring
{
@synchronized(self)
{
if (_source)
{
return;
}
_fileDescriptor = open([_URL.path fileSystemRepresentation], O_EVTONLY);
if (!_fileDescriptor) {
return;
}
// watch the file descriptor for writes
_source = dispatch_source_create(DISPATCH_SOURCE_TYPE_VNODE, _fileDescriptor, DISPATCH_VNODE_WRITE, _queue);
// call the passed block if the source is modified
dispatch_source_set_event_handler(_source, _block);
// close the file descriptor when the dispatch source is cancelled
dispatch_source_set_cancel_handler(_source, ^{
close(_fileDescriptor);
});
// at this point the dispatch source is paused, so start watching
dispatch_resume(_source);
}
}
- (void)stopMonitoring
{
@synchronized(self)
{
if (!_source)
{
return;
}
dispatch_source_cancel(_source);
#if !OS_OBJECT_USE_OBJC
dispatch_release(_source);
#endif
_source = nil;
}
}
@end