如何创建NSMetaDataQuery并在后台线程上获取结果?

时间:2014-03-01 09:46:42

标签: ios nsoperationqueue nsmetadataquery

默认情况下NSMetaDataQuery会在主线程上收到结果通知。您似乎必须在主线程上调用query.startQuery,但您可以使用[query.setOperationQueue:]来设置将向其发送结果通知的队列。

理想情况下,我希望后台线程接收这些结果并处理它们,并根据找到的文件,我将设置变量或将通知发布到主线程。

我不明白的是我如何创建操作队列以及如何处理此队列上的通知。需要任何类的示例代码以及创建它们的位置和方式的详细信息都很棒。我已经阅读了Apple文档,但无法理解如何创建可以处理通知的队列。

由于

2 个答案:

答案 0 :(得分:4)

您可以尝试使用此代码处理后台线程中的通知:

   NSMetadataQuery *query = [NSMetadataQuery new];
   [query enableUpdates];
   // Subscribe to query updates and process then in background thread
   [[NSNotificationCenter defaultCenter] addObserverForName:
    NSMetadataQueryDidUpdateNotification
   object:nil queue:[NSOperationQueue new]
   usingBlock:^(NSNotification __strong *notification)
   {
      // disable the query while iterating
    [query disableUpdates];
     for (NSMetadataItem *item in query.results)
     {
         //do here everything you want with the results 
        //e.g. get values with [item valueForAttribute:NSMetadataItemFSNameKey];
         }          
       [query enableUpdates];
        }];
    [query startQuery];

仅为提示:

 [NSOperationQueue mainQueue] // added operations execute on the main thread
 [NSOperationQueue new] // iOS 4 and higher - guaranteed to be on the background thread

PS处理您应该订阅NSMetadataQueryDidFinishGatheringNotification的第一个结果 - 当接收者完成查询的初始结果收集阶段以及所有后续更新时,它将被发布应该在我的示例中订阅NSMetadataQueryDidUpdateNotification,因为您知道查询有两个阶段:收集所有当前匹配结果的初始收集阶段和第二个实时更新阶段。

答案 1 :(得分:1)

这非常有帮助。这是我在Swift中实现的代码,如果有人在寻找这个:

let nf = NotificationCenter.default

    //add background queue observer for updates during live phase
    nf.addObserver(forName: NSNotification.Name.NSMetadataQueryDidUpdate, object: nil, queue: self.backGroundQueue, using:{_ in 
        self.query.disableUpdates()
        self.resultsArray = self.query.results as! [ResultItem]
        self.query.enableUpdates()
    })

    //add background queue observer for updates during gathering
    nf.addObserver(forName: NSNotification.Name.NSMetadataQueryGatheringProgress, object: nil, queue: self.backGroundQueue, using:{_ in
        self.query.disableUpdates()
        self.resultsArray = self.query.results as! [ResultItem]
        print("progressing... ")
        print("number of results: \(self.query.results.count)")
        self.query.enableUpdates()
    })

    //add background queue observer for finishing gathering phase
    nf.addObserver(forName: NSNotification.Name.NSMetadataQueryDidFinishGathering, object: nil, queue: self.backGroundQueue, using:{_ in
        self.query.disableUpdates()
        self.resultsArray = self.query.results as! [ResultItem]
        self.query.enableUpdates()
    })


    self.query.searchScopes = [self.thePath]
    self.query.predicate = self.getPredicateToRun()

    self.query.start()