【问题标题】:How to cancel DispatchQueue.main.asyncAfter(deadline: time) in Swift3? [duplicate]如何在 Swift3 中取消 DispatchQueue.main.asyncAfter(deadline: time)? [复制]
【发布时间】:2016-10-04 09:18:58
【问题描述】:

说明:

我目前正在使用以下代码来查看用户是否已停止在 searchBar 中输入。每当用户在0.5 秒后立即开始输入时,我想取消它。

代码:

DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
    // your function here
}

问题:

如果用户再次开始输入Swift3,我该如何取消DispatchQueue.main.asyncAfter

我尝试过的:

我之前尝试过实现:

NSObject.cancelPreviousPerformRequests(withTarget: self)
self.perform(Selector(("searchForText:")), with: searchString, afterDelay: 0.5)

但是延迟似乎无法正常工作。

更多代码:

//In class SearchViewController: UITableViewController, UISearchResultsUpdating
func updateSearchResults(for searchController: UISearchController) {
    let searchString: String = searchController.searchBar.text!

    //This is what I previously tried.. which doesn't work...
    //NSObject.cancelPreviousPerformRequests(withTarget: self)
    //self.perform(Selector(("searchForText:")), with: searchString, afterDelay: 0.5)

    //A struct with the first example code shown above.
    Utils.Dispatch.delay(secondsToDelay: 1){
        print("1 second has passed ! " + searchString)
    }
}

【问题讨论】:

  • 试试这个stackoverflow.com/questions/39744291/… 是否有效
  • 我推荐你使用NSOperation,你将能够在操作之间添加依赖并重用、取消或暂停它们。
  • 我找到了解决方案,当我完全确定它有效时,我会发布它作为答案。
  • 您是否验证了您的解决方案?我现在也遇到同样的问题...
  • 编辑:这里显然...stackoverflow.com/a/39684520/2387365

标签: swift swift3 tvos


【解决方案1】:

对于那些有时间测试代码的人,我将发布我当前未经测试的解决方案。当我有时间尝试时,我会编辑帖子。

private var operationQueue: OperationQueue!
private var mainAsyncQueue: DispatchQueue?


override func viewDidLoad() {
    print("ViewDidLoad of SearchViewController called")

    self.operationQueue = OperationQueue()
    self.currentTime = DispatchTime.now()

}
// MARK: UISearchResultsUpdating

func updateSearchResults(for searchController: UISearchController) {
    let searchStringRaw: String = searchController.searchBar.text!
    let searchString = searchStringRaw.trimmingCharacters(in: .whitespacesAndNewlines)
    guard searchString.characters.count > 0 else {
        return
    }

    print("Search string: \(searchString)")
    self.operationQueue.cancelAllOperations()
    //Put this in Utils.Dispatch.Delay
    self.mainAsyncQueue = DispatchQueue(label: "search.operation." + String(describing: DispatchTime.now()), qos: .default, attributes: DispatchQueue.Attributes.concurrent)

    let time = DispatchTime.now()
    self.currentTime = time

    self.mainAsyncQueue!.asyncAfter(deadline: time + 1){
        guard self.currentTime == time else {
            return
        }

        let tempOperation = BlockOperation(block:{

            if let nsurl: URL = Utils.Url.generate(Constants.Url.Search, options: "&p=1&n=20&q="+searchString.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed)!){
                //Download data and handle response

            } else {
                print("Something went wrong...")
            }


        })
        self.operationQueue.addOperation(tempOperation)
    }

}

【讨论】:

  • 谢谢,kemicofa。在我的使用中,我必须在 blockOperation 中使用DispatchQueue.main.async {} 来运行我的代码,因为它是一个自动布局动画。干得好!
  • 迷失的灵魂需要这个来做一些简单的事情,这可能会引起你的兴趣:stackoverflow.com/questions/48016111/…
猜你喜欢
  • 2017-04-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-04
  • 2017-03-12
  • 1970-01-01
  • 2014-01-31
  • 2017-09-05
  • 2019-11-01
相关资源
最近更新 更多