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