API からデータをフェッチし、それに応じてメニューを更新する小さな systray アプリケーションを作成していますが、開いているときにメニューを更新するのに問題があります。
どこから始めればいいのかわからないので、最初から始めましょう。
PNLinksLoader
データを取得して解析することを担当するカスタムクラスがあります。
- (void)loadLinks:(id)sender
{
// instance variable used by the NSXMLParserDelegate implementation to store data
links = [NSMutableArray array];
[NSURLConnection sendAsynchronousRequest:request queue:[[NSOperationQueue alloc] init] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
NSXMLParser *parser = [[NSXMLParser alloc] initWithData:data];
parser.delegate = self;
if (YES == [parser parse]) {
NSArray *modes = [NSArray arrayWithObject:NSRunLoopCommonModes];
[delegate performSelectorOnMainThread:@selector(didEndLoadLinks:) withObject:links waitUntilDone:NO modes:modes];
}
}];
}
ローダーは、アプリケーションの起動時に 1 回実行され (完全に動作します)、定期的な更新のためにタイマーが設定されます。
loader = [[PNLinksLoader alloc] init];
[loader setRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://papyrus.pandanova.com/links"]]];
[loader setDelegate:self];
[loader loadLinks:self];
NSMethodSignature *signature = [loader methodSignatureForSelector:@selector(loadLinks:)];
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
[invocation setTarget:loader];
[invocation setSelector:@selector(loadLinks:)];
NSTimer *timer = [NSTimer timerWithTimeInterval:10 invocation:invocation repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
ローダーがサーバーに新しいデータをロードするたびに、メニューが閉じられていれば、すべて問題ありません。メニューを開くと、新しいデータがそこにあります。
ただし、更新中にメニューが開いている場合は、何も起こりません。メニューを閉じて再度開くと、新しいデータが表示されます。
RunLoop について何かが欠けていると思いますが、何がわかりません (Objective-C を学ぶためにこの小さなアプリを実際に書いているので、それについての私の理解は非常にまばらです)。
編集
ここでの問題は、開いているときにメニューを更新しないことです。実際には、ローダーのperformSelector:withObject:
代わりに使用すると機能します。performSelectorOnMainThread:withObject:waitUntilDone:modes:
問題は、メニューが開いているときにメニューを更新すると、奇妙な結果が得られることです(メニューが閉じているときに完全に機能します)。
NSLog
メニュー人口ループに呼び出しを追加するとfixes
症状がループし、インターネットで読んだことから、スレッドに競合状態があることを示している可能性があります(そのため、を使用しようとしperformSelectorOnMainThread
ましたが、理解できないようです)アウト。