私は定期的にプラグイン (NSBundles をロード) を使用して、いくつかの機能をカプセル化しています。プラグインの 1 つで NSMetadataQuery を使用したいのですが、解決できないスレッドの問題に遭遇しました。
プラグインのメイン クラス内で、次のようにクエリを設定します。
NSMetadataQuery *mdQuery = [[NSMetadataQuery alloc] init];
[mdQuery setPredicate:[NSPredicate predicateWithFormat:@"(kMDItemFSName LIKE 'Project *')"]];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(processQuery:)
name:nil
object:mdQuery];
[mdQuery startQuery];
そして、通知は次の方法でキャッチされます。
- (void)processQuery:(NSNotification *)notification
{
NSMetadataQuery *mdQuery = [notification object];
if ([[notification name] isEqualToString:NSMetadataQueryDidStartGatheringNotification]) {
NSLog(@"%@ %@ Query started", [self class], NSStringFromSelector(_cmd));
} else if ([[notification name] isEqualToString:NSMetadataQueryGatheringProgressNotification]) {
NSLog(@"%@ %@ %ld", [self class], NSStringFromSelector(_cmd), (long)[mdQuery resultCount]);
} else if ([[notification name] isEqualToString: NSMetadataQueryDidFinishGatheringNotification]) {
NSUInteger theResultCount = [mdQuery resultCount];
theResultCount = 10; //for now
for (NSUInteger i; i < theResultCount; i++) {
NSLog(@"%@ %@ %ld %@", [self class], NSStringFromSelector(_cmd), (long)i, [mdQuery resultAtIndex:i]);
}
} else {
NSLog(@"%@ %@ NSMetadataQueryDidUpdateNotification: %@", [self class], NSStringFromSelector(_cmd), notification);
}
}
このコードはアプリで実行すると問題なく動作しますが、プラグインから実行すると、NSMetadataQueryDidStartGatheringNotification のみが受信され、それ以外は何も受信されません。
同じ問題に取り組んでいる人々の投稿を 1 つまたは 2 つ見つけました。そのうちの 1 つ ( James Bucanek in Oh notifications, where are you? ) は、CFRunLoopRun(); を呼び出して彼の問題を解決しました。startQuery および CFRunLoopStop(CFRunLoopGetCurrent ()); の直後。クエリが実行されたとき。1 つの問題は、このように開始された実行ループが同期的であるのに対し、NSMetadataQuery は明らかに非同期であることです。もう 1 つの問題は、プラグインで NSMetadataQueryGatheringProgressNotification を通過できなかったことです。次に、NSMetadataQuery に独自のスレッドを与えようとしましたが、NSMetadataQueryDidStartGatheringNotification しか受信されませんでした。問題が解決するかどうかはわかりませんが、本当にいくつかの意見が欲しいです。