faultier #4047(2007/11/15 06:27 GMT) [ Objective-C ] Rating1/1=1.00
NSRunLoopで回すのはいいのかどうか分かりません。NSTimerを使いたくてこの形に。 一応Leopardタグ付けますがfor ~ in ~のところをNSEnumeratorを使うように書き換えればXcode2.xでもコンパイルできるはず。 あと、Leopardだとそのままずばりファイルの監視をするFSEventというAPIがあります。 TimeMachineが使ってるやつ。これはCなんですが、詳細は参考ページ参照で。
see: Watcher(FSEvent APIの使用例)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
#import <Foundation/Foundation.h> #define WATCH_PATH @"target path" #define WATCH_FILE_ATTR @"target file atrributes" #define WATCH_FILE_MODIFIED @"target file modified" @interface Watcher : NSObject { NSMutableDictionary *targetPathes; NSFileManager *manager; NSMutableDictionary *fileAttributes; } - (id)initWithTargetPathes:(NSArray *)pathes; - (void)checkModified; @end @implementation Watcher - (id)initWithTargetPathes:(NSArray *)pathes; { targetPathes = [NSMutableDictionary dictionary]; manager = [NSFileManager defaultManager]; fileAttributes = [NSMutableDictionary dictionary]; for (NSString *path in pathes) { [targetPathes setValue:path forKey:path]; NSDictionary *status = [manager fileAttributesAtPath:path traverseLink:YES]; if (status) [fileAttributes setValue:status forKey:path]; } return self; } - (void)sendNotification:(NSString *)aPath withStatus:(id)aStatus { NSString *message = [NSString stringWithFormat:@"'%@' is modified!", aPath]; [[NSNotificationCenter defaultCenter] postNotificationName:WATCH_FILE_MODIFIED object:message userInfo:aStatus]; return; } - (void)checkModified { for (NSString *path in targetPathes) { NSAutoreleasePool *pool = [NSAutoreleasePool new]; NSDictionary *_prev = [fileAttributes objectForKey:path]; NSDictionary *_current = [manager fileAttributesAtPath:path traverseLink:YES]; if (_prev || _current) { if (!_current) { [fileAttributes removeObjectForKey:path]; [self sendNotification:path withStatus:nil]; } else if (![_current isEqual:_prev]) { [fileAttributes setObject:[_current copy] forKey:path]; [self sendNotification:path withStatus:_current]; } } [pool release]; } return; } @end @interface FileStatusLogger : NSObject { NSNotificationCenter* center; } - (id)initWithNotificationCenter:(NSNotificationCenter *)aCenter; - (void)log:(NSNotification *)notice; @end @implementation FileStatusLogger - (id)initWithNotificationCenter:(NSNotificationCenter *)aCenter { [super init]; [aCenter addObserver:self selector:@selector(log:) name:WATCH_FILE_MODIFIED object:nil]; return self; } - (id)init { return [self initWithNotificationCenter:[NSNotificationCenter defaultCenter]]; } - (void)log:(NSNotification *)notice; { NSLog(@"%@", [notice object]); return; } @end void usage(name) { printf("Usage: %s <interval> <duration> <path1> [<path2>...]\n", name); exit(1); } int main(int argc, char *argv[]) { if (argc < 4) usage(argv[0]); NSAutoreleasePool *pool = [NSAutoreleasePool new]; NSMutableArray *pathes = [NSMutableArray array]; NSTimeInterval interval = strtod(argv[1], NULL); NSTimeInterval duration = strtod(argv[2], NULL); if (interval <= 0) usage(argv[0]); int i; for (i = 3; i < argc; i++) { [pathes addObject:[NSString stringWithCString:argv[i]]]; } Watcher *watcher = [[Watcher alloc] initWithTargetPathes:pathes]; FileStatusLogger *logger = [FileStatusLogger new]; NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:interval target:watcher selector:@selector(checkModified) userInfo:nil repeats:YES]; NSLog(@"monitoring start"); [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode]; if (duration > 0) { [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:duration]]; } else { [[NSRunLoop currentRunLoop] run]; } NSLog(@"monitoring end"); [pool release]; return 0; }
Rating1/1=1.00-0+
1 reply [ reply ]
匿名 #7915(2008/11/01 06:05 GMT) Rating0/0=0.00
116行目のscheduledTimerWithTimeInterval:target:selector:userInfo:repeats: のメソッドでcurrentRunLoopに登録されますので、 122行目の addTimer:...はいらないんじゃないかなぁ。
[ reply ]
faultier
#4047()
[
Objective-C
]
Rating1/1=1.00
see: Watcher(FSEvent APIの使用例)
Rating1/1=1.00-0+
1 reply [ reply ]