首先我們來看一下下面這個方法:
func addTarget(_ target: Any?, action: Selector, for controlEvents: UIControlEvents)
其中的Selector 源自 Objective-C钻洒,例如 SEL 類型,以及 @selector() 方法選擇器舟误。由于Swift語法體系不含有消息機制,所以這里只能借助Cocoa Framework本身的消息機制來了。而Swift中所引入的Select()也是為了迎合action這里的selector民傻,Swift 中也兼容了這個概念。
Selector結(jié)構(gòu)體
先來看一下Selector的源碼:
public struct Selector : ExpressibleByStringLiteral {
/// Create a selector from a string.
public init(_ str: String)
/// Create an instance initialized to `value`.
public init(unicodeScalarLiteral value: String)
/// Construct a selector from `value`.
public init(extendedGraphemeClusterLiteral value: String)
/// Create an instance initialized to `value`.
public init(stringLiteral value: String)
}
extension Selector : Equatable, Hashable {
/// The hash value.
///
/// **Axiom:** `x == y` implies `x.hashValue == y.hashValue`
///
/// - Note: the hash value is not guaranteed to be stable across
/// different invocations of the same program. Do not persist the
/// hash value across program runs.
public var hashValue: Int { get }
}
extension Selector : CustomStringConvertible {
/// A textual representation of `self`.
public var description: String { get }
}
extension Selector : CustomReflectable {
/// Returns a mirror that reflects `self`.
public var customMirror: Mirror { get }
}
從中可以看出selector其實是一個結(jié)構(gòu)體。它實現(xiàn)了字面量的協(xié)議漓踢,可以使用字符串直接定義selector牵署。
Selector的幾種初始化方法
#第一種
aButton.addTarget(self,
action: Selector("aButtonClick"),
for: .touchUpInside)
#第二種
bButton.addTarget(self,
action: #selector(bButtonClick),
for: .touchUpInside)
若是 Swift 中的私有方法,則必須賦予其 Objective-C 的 runtime(運行時)喧半。即在方法名前加上 @objc
:
@IBOutlet weak var wgButton: UIButton!
@IBOutlet weak var anotherWgButton: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
wgButton.addTarget(self,
action: #selector(wgButtonClick),
for: .touchUpInside)
}
@objc func wgButtonClick(_ button: UIButton) {
let btnLabel = button.titleLabel?.text ?? "nil"
print(btnLabel)
print(#function)
}