cancelPreviousPerformRequests似乎不适用于Swift 3.0

Qua*_*ees 2 ios swift3

正如标题所述,由于某种原因,以下(简化)代码不起作用:

extension InputView: {

    func updateTable(text: String) {
            NSObject.cancelPreviousPerformRequests(withTarget: self, selector: #selector(loadPlaces(text:)), object: nil)
          //NSObject.cancelPreviousPerformRequests(withTarget: self)

            self.perform(#selector(loadPlaces(text:)), with: text, afterDelay: 0.5)

            prevSearch = inputField.text!;
        }

    //Private wrapper function
    @objc private func loadPlaces(text: String) {
        print("loading results for: \(text)")
       // locator?.searchTextHasChanged(text: text)
    }
}
Run Code Online (Sandbox Code Playgroud)

updateTable每当用户编辑一个UITextField调用时localPlaces,我就会调用,调用哪个调用调用google的在线位置API(注释掉)的函数.不幸的是,每次调用updateTable后都会调用loadPlaces中的打印行.从我的视觉检查来看,实际上打印报表实际上有延迟,但旧的通话不会取消.我试过看了很多StackOverflow线程,但是我找不到任何针对Swift 3的更新内容.我是否正在调用错误的内容?

PS.如果我改为使用注释掉的单参数,cancelPreviousPerformRequests.它的作用是出于某种原因.


编辑:我已经能够在一个单独的项目中复制此错误.所以我100%确定上面的代码是错误的.如果您想复制此错误,请打开一个新的iOS项目并将以下代码粘贴到默认值中ViewController:

class InputView: UIView {

    func updateTable(text: String) {
        NSObject.cancelPreviousPerformRequests(withTarget: self, selector: #selector(loadPlaces(text:)), object: nil)

        self.perform(#selector(loadPlaces(text:)), with: text, afterDelay: 0.5)

    }

    //Private wrapper function
    @objc private func loadPlaces(text: String) {
        print("loading results for: \(text)")
        // locator?.searchTextHasChanged(text: text)
    }
}




class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

        let input = InputView()

        for i in 0..<200 {
            input.updateTable(text: "Call \(i)")
        }
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }


}
Run Code Online (Sandbox Code Playgroud)

OOP*_*Per 7

Duncan C的答案中的解释不适合这种情况.

在参考cancelPreviousPerformRequests(withTarget:selector:object:):

讨论

取消所有执行请求,其目标与aTarget,参数anArgument和选择器相同 aSelector.

所以,当你有一条像:

<aTarget>.perform(<aSelector>, with: <anArgument>, afterDelay: someDelay)
Run Code Online (Sandbox Code Playgroud)

你可以用以下方法取消它:

NSObject.cancelPreviousPerformRequests(withTarget: <aTarget>, selector: <aSelector>, object: <anArgument>)
Run Code Online (Sandbox Code Playgroud)

只有当所有的3样东西aTarget,aSelector anArgument比赛.


请尝试这样的事情并检查你看到的内容:

class InputView: UIView {

    var lastPerformArgument: NSString? = nil

    func updateTable(text: String) {
        NSObject.cancelPreviousPerformRequests(withTarget: self, selector: #selector(loadPlaces(text:)), object: lastPerformArgument)

        lastPerformArgument = text as NSString
        self.perform(#selector(loadPlaces(text:)), with: lastPerformArgument, afterDelay: 0.5)

    }

    //Private wrapper function
    @objc private func loadPlaces(text: String) {
        print("loading results for: \(text)")
        // locator?.searchTextHasChanged(text: text)
    }
}
Run Code Online (Sandbox Code Playgroud)