NSMetadataQueryDidFinishGatheringNotification 从未调用过
NSMetadataQueryDidFinishGatheringNotification never called
尝试运行以下代码:
#import <Foundation/Foundation.h>
@interface FileQuery : NSObject
@end
@interface FileQuery()
@property (nonatomic, strong) NSMetadataQuery *query;
@property (nonatomic, strong) NSMutableArray<NSURL *> *fileArray;
@end
@implementation FileQuery
-(void)stopQuery {
if (_query) {
NSLog(@"No longer watching iCloud dir...");
[[NSNotificationCenter defaultCenter] removeObserver:self name:NSMetadataQueryDidFinishGatheringNotification object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self name:NSMetadataQueryDidUpdateNotification object:nil];
[_query stopQuery];
_query = nil;
_fileArray = nil;
}
}
-(BOOL)startQuery:(NSString *)suffix {
[_query stopQuery];
dispatch_async(dispatch_get_global_queue(0, 0), ^{
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(processFiles:)
name:NSMetadataQueryDidFinishGatheringNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(processFiles:)
name:NSMetadataQueryDidUpdateNotification
object:nil];
_query = [NSMetadataQuery new];
if (_query) {
NSLog(@"aa");
_fileArray = [NSMutableArray new];
[_query setSearchScopes:@[NSMetadataQueryLocalComputerScope]];
[_query setPredicate:[NSPredicate predicateWithFormat:@"%K BEGINSWITH %@",
NSMetadataItemFSNameKey, suffix]];
dispatch_async(dispatch_get_main_queue(), ^{
if ([_query startQuery]) {
[_query enableUpdates];
NSLog(@"Finished with query = %@, predicate = %@", _query, _query.predicate);
}
});
}
});
NSLog(@"bb");
return TRUE;
}
- (void)processFiles:(NSNotification *)notification {
[_query disableUpdates];
// The query reports all files found, every time.
NSArray * queryResults = [_query results];
NSLog(@"Results = %@", queryResults);
for (NSMetadataItem * result in queryResults) {
NSURL * fileURL = [result valueForAttribute:NSMetadataItemURLKey];
NSLog(@"file = %@", fileURL);
[_fileArray addObject:fileURL];
}
[self stopQuery];
}
@end
int main(int argc, char *argv[]) {
if (argc != 2) {
NSLog(@"Error in number of params");
return 0;
}
NSString *s = [NSString stringWithFormat:@"%s", argv[1]];
NSLog(@"suffix = %@", s);
FileQuery *q = [FileQuery new];
if ([q startQuery:s]) {
while(true) {
NSLog(@"1");
sleep(100);
}
} else {
NSLog(@"query failed");
}
return 0;
}
出于某种原因,从未调用 NSMetadataQueryDidFinishGatheringNotification。
此外,NSMetadataQueryDidUpdateNotification 通知也从未被调用。
有人知道为什么吗?
有没有人对 Spotlight 搜索文件有更好的想法?
非常感谢!
当我进行一次修改时,您的代码可以在我的机器上运行。不要在循环中调用 sleep
,而是调用 CFRunLoopRun()
:
int main(int argc, char *argv[]) {
...
if ([q startQuery:s]) {
CFRunLoopRun();
} else {
NSLog(@"query failed");
}
return 0;
}
通知机制是使用 运行 循环实现的,因此您必须有一个 运行ning 才能发挥它的魔力。
尝试运行以下代码:
#import <Foundation/Foundation.h>
@interface FileQuery : NSObject
@end
@interface FileQuery()
@property (nonatomic, strong) NSMetadataQuery *query;
@property (nonatomic, strong) NSMutableArray<NSURL *> *fileArray;
@end
@implementation FileQuery
-(void)stopQuery {
if (_query) {
NSLog(@"No longer watching iCloud dir...");
[[NSNotificationCenter defaultCenter] removeObserver:self name:NSMetadataQueryDidFinishGatheringNotification object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self name:NSMetadataQueryDidUpdateNotification object:nil];
[_query stopQuery];
_query = nil;
_fileArray = nil;
}
}
-(BOOL)startQuery:(NSString *)suffix {
[_query stopQuery];
dispatch_async(dispatch_get_global_queue(0, 0), ^{
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(processFiles:)
name:NSMetadataQueryDidFinishGatheringNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(processFiles:)
name:NSMetadataQueryDidUpdateNotification
object:nil];
_query = [NSMetadataQuery new];
if (_query) {
NSLog(@"aa");
_fileArray = [NSMutableArray new];
[_query setSearchScopes:@[NSMetadataQueryLocalComputerScope]];
[_query setPredicate:[NSPredicate predicateWithFormat:@"%K BEGINSWITH %@",
NSMetadataItemFSNameKey, suffix]];
dispatch_async(dispatch_get_main_queue(), ^{
if ([_query startQuery]) {
[_query enableUpdates];
NSLog(@"Finished with query = %@, predicate = %@", _query, _query.predicate);
}
});
}
});
NSLog(@"bb");
return TRUE;
}
- (void)processFiles:(NSNotification *)notification {
[_query disableUpdates];
// The query reports all files found, every time.
NSArray * queryResults = [_query results];
NSLog(@"Results = %@", queryResults);
for (NSMetadataItem * result in queryResults) {
NSURL * fileURL = [result valueForAttribute:NSMetadataItemURLKey];
NSLog(@"file = %@", fileURL);
[_fileArray addObject:fileURL];
}
[self stopQuery];
}
@end
int main(int argc, char *argv[]) {
if (argc != 2) {
NSLog(@"Error in number of params");
return 0;
}
NSString *s = [NSString stringWithFormat:@"%s", argv[1]];
NSLog(@"suffix = %@", s);
FileQuery *q = [FileQuery new];
if ([q startQuery:s]) {
while(true) {
NSLog(@"1");
sleep(100);
}
} else {
NSLog(@"query failed");
}
return 0;
}
出于某种原因,从未调用 NSMetadataQueryDidFinishGatheringNotification。
此外,NSMetadataQueryDidUpdateNotification 通知也从未被调用。
有人知道为什么吗? 有没有人对 Spotlight 搜索文件有更好的想法?
非常感谢!
当我进行一次修改时,您的代码可以在我的机器上运行。不要在循环中调用 sleep
,而是调用 CFRunLoopRun()
:
int main(int argc, char *argv[]) {
...
if ([q startQuery:s]) {
CFRunLoopRun();
} else {
NSLog(@"query failed");
}
return 0;
}
通知机制是使用 运行 循环实现的,因此您必须有一个 运行ning 才能发挥它的魔力。