【问题标题】:NSMetadataQueryDidFinishGatheringNotification never calledNSMetadataQuery DidFinish 收集通知从未调用
【发布时间】:2018-02-12 04:19:06
【问题描述】:

尝试运行以下代码:

#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 文件搜索有更好的想法吗?

非常感谢!

【问题讨论】:

    标签: objective-c notifications spotlight


    【解决方案1】:

    当我进行一次修改时,您的代码可以在我的机器上运行。不要在循环中调用sleep,而是调用CFRunLoopRun()

    int main(int argc, char *argv[]) {
        ...
    
        if ([q startQuery:s]) {
            CFRunLoopRun();
        } else {
            NSLog(@"query failed");
        }
    
        return 0;
    }
    

    通知机制是使用运行循环实现的,因此您必须运行它才能发挥它的魔力。

    【讨论】:

      猜你喜欢
      • 2012-01-08
      • 2014-06-21
      • 2019-03-20
      • 1970-01-01
      • 1970-01-01
      • 2018-10-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多