swift类里的函数

看一下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")
    }
}

相关推荐