自定义实现类似UIButton
的addTarget
事件响应链
沿用OC调用方式
动态调用
声明
weak var target: AnyObject?;
var action: Selector?;
func addTarget(_ target: AnyObject, selector: Selector) {
self.target = target;
self.action = selector;
}
调用
if let target = target, let selector = action {
if let method = class_getInstanceMethod(type(of: target), selector) {
let imp = method_getImplementation(method);
typealias Function = @convention(c) (AnyObject, Selector, Any?) -> ();
let function = unsafeBitCast(imp, to: Function.self);
function(target, selector, self);
}
}
Swift Curring柯里化
方式
声明
protocol TargetAction {
func performAction();
}
struct TargetActionWrapper<T: AnyObject>: TargetAction {
weak var target: T?;
let action: (T) -> () -> ();
func performAction() {
if let t = target {
action(t)();
}
}
}
class Model: NSObject {
var wrapper: TargetAction?
func addTarget<T: AnyObject>(target: T, action: @escaping (T) -> () -> ()) {
wrapper = TargetActionWrapper(target: target, action: action);
}
func invoke() {
wrapper?.performAction();
}
}
调用
let model = Model();
model.addTarget(target: self, action: Test.invokeAction);
func invokeAction() {}
上面方法无法传递参数,需要进一步扩展。扩展可以根据自己需要,此处只简单举例。
protocol TargetAction {
func performAction(_ userInfo: Any?);
}
struct TargetActionWrapper<T: AnyObject>: TargetAction {
weak var target: T?;
let action: (T) -> (Any?) -> ();
func performAction(_ userInfo: Any?) {
if let t = target {
action(t)(userInfo);
}
}
}
class Model: NSObject {
var wrapper: TargetAction?
var userInfo: Any?;
func addTarget<T: AnyObject>(target: T, action: @escaping (T) -> (Any?) -> (), userInfo: Any? = nil) {
self.userInfo = userInfo;
wrapper = TargetActionWrapper(target: target, action: action);
}
func invoke() {
wrapper?.performAction(userInfo);
}
}
// 调用
let model = Model();
model.addTarget(target: self, action: Test.invokeAction, userInfo: ["a": "b"]);
func invokeAction(_ sender: Any) {}