一个工具的觉悟 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")
    }
}