How do you know which string to provide as a selector for Swift functions?

久未见 提交于 2020-01-07 02:51:31

问题


Sometimes when I am working with selectors in Swift (i.e. the Selector type), the string literal that I provide for the action parameter to methods like targetForAction(_:withSender:) or addTarget(_:action:) doesn't invoke or map to the actual Swift function to which I am expecting.

For example, when an instance of MyResponder as shown below is in the responder chain, it cannot be found when calling targetForAction(_:withSender) using the string showImage:. What is the pattern for knowing what is the proper string literal to provide for different types of Swift function signatures and the options for required and/or omitted argument labels?

import UIKit

class MyResponder: UIResponder {

    func showImage( named filename: String ) {
        print( "Loading image..." )
    }
}

class MyViewController: UIViewController {

    @IBAction func buttonTapped( sender: AnyObject? ) {
        if let responder = self.targetForAction( "showImage:", withSender: self ) as? MyResponder {
            responder.showImage(named: "my_image" )
        }
    }
}

回答1:


With some trial, error and encouragement from commenters, I managed to figure out the pattern!

The string literal has to follow Objective-C syntax translated from the signature of your Swift function, which is an interesting tidbit that wasn't obvious at first, but makes perfect sense when you consider the purpose things like the @objc attribute. In writing up a better code sample, I seem to have figured out the pattern for the mappings myself.

functionName + (With + First) + : + (second) + : etc.

Where what's in the parenthesis is required only when the argument label is required (i.e. not omitted). And remember to capitalize With and First.

In each of the following examples, myObject will return itself as the target for the provided selector, indicating that the string literal provided as the Selector did in fact map that the Swift function for which it was intended.

import UIKit

class MyObject : UIResponder {
    func someFunction() {}
    func someFunction(param:String) {}
    func someLabeledFunction(param param:String) {}
    func someTwoArgumentFunction(param1:String, param2:String) {}
    func someTwoArgumentNoLabelFunction(param1:String, _ param2:String) {}
    func someHalfLabeledTwoArgumentFunction(param1 param1:String, _ param2:String) {}
    func someCompletelyLabeledTwoArgumentFunction(param1 param1:String, param2:String) {}
}

let myObject = MyObject()
myObject.targetForAction("someFunction", withSender: nil)
myObject.targetForAction("someFunction:", withSender: nil)
myObject.targetForAction("someLabeledFunctionWithParam:", withSender: nil)
myObject.targetForAction("someTwoArgumentFunction:param2:", withSender: nil)
myObject.targetForAction("someTwoArgumentNoLabelFunction::", withSender: nil)
myObject.targetForAction("someHalfLabeledTwoArgumentFunctionWithParam1::", withSender: nil)
myObject.targetForAction("someCompletelyLabeledTwoArgumentFunctionWithParam1:param2:", withSender: nil)


来源:https://stackoverflow.com/questions/31198541/how-do-you-know-which-string-to-provide-as-a-selector-for-swift-functions

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!