【问题标题】:How do I create a NSMetaDataQuery and get results on a background thread?如何创建 NSMetaDataQuery 并在后台线程上获取结果?
【发布时间】:2014-04-02 11:46:18
【问题描述】:

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

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

我不明白我如何创建操作队列以及如何处理此队列上的通知。所需的任何类的示例代码以及应在何处以及如何创建它们的详细信息都会很棒。我已阅读 Apple 文档,但无法理解您如何创建可以处理通知的队列。

谢谢

【问题讨论】:

    标签: ios nsoperationqueue nsmetadataquery


    【解决方案1】:

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

       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,如我的例如,因为您知道查询有两个阶段:收集所有当前匹配结果的初始收集阶段和第二个实时更新阶段。

    【讨论】:

    • 谢谢,看起来很棒,很简单!我会在几个小时内试一试,以确认它是否有效。
    【解决方案2】:

    这很有帮助。这是我用来在 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()
    

    【讨论】:

    • 如何声明self.backGroundQueue和self.query?
    猜你喜欢
    • 1970-01-01
    • 2012-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多