一个工具的觉悟 2015-06-12
看一下swift对函数是怎么定义的
如果函数是在一个类里的话,用法通常和其他面向对象语言比如Java没啥区别。无非就是做成类实例,调用函数。
class Myclass{ func hello(name:String){ println("hello, \(name)") } } let mycls = Myclass() mycls.hello("wqf")
但是和java一类语言不同的是,swift类(当然也包括结构体,枚举)里的函数都是柯里化的,而且接受类实例为参数,所以可以这么用
let helloFunc = Myclass.hello let mycls = Myclass() helloFunc(mycls)("wqf")
这种调用方法和上面那个是等价的。
但从形式上来看是不是有点儿像java的反射机制?不同的是那个用的是方法的字符串名,而且工作原理也不一样。
大家都知道swift里target-action的调用是没有办法用@selector的,都是直接指定字符串的。
指定字符串的好处当然就是比较自由,但是对于swift来说也面临着无法refactor的问题。
实际上既然类里的函数都是柯里化的,我觉得其实都可以直接用[类名.函数名]的形式来指定action了,由内部来按照上面的形式调用多好。
既然没这么做,那么我们可以自己这么做。
参照以下代码,来自这个blog
protocol TargetAction { func performAction() } struct TargetActionWrapper<T: AnyObject> : TargetAction { weak var target: T? let action: (T) -> () -> () func performAction() -> () { if let t = target { action(t)() } } } enum ControlEvent { case TouchUpInside case ValueChanged // ... } class Control { var actions = [ControlEvent: TargetAction]() func setTarget<T: AnyObject>(target: T, action: (T) -> () -> (), controlEvent: ControlEvent) { actions[controlEvent] = TargetActionWrapper(target: target, action: action) } func removeTargetForControlEvent(controlEvent: ControlEvent) { actions[controlEvent] = nil } func performActionForControlEvent(controlEvent: ControlEvent) { actions[controlEvent]?.performAction() } }
使用
class MyViewController { let button = Control() func viewDidLoad() { button.setTarget(self, action: MyViewController.onButtonTap, controlEvent: .TouchUpInside) } func onButtonTap() { println("Button was tapped") } }