这里写目录标题
- 前言
- 使用场景
- 场景1 perform执行方法的时候
- 场景2 timer运行的时候,要执行一个方法
- forwardingTarget方法的作用
- demo代码下载
前言
- (这段可以不看)之前看了关于forwardingTarget的文章,太长了,99%的文字讲的不是如何使用,是里面一大堆整体功能的讲解,看完以后太浪费时间,所以今天我把这1%真正我们要用的功能和原理写出来,目的就是为了节省大家时间,让文章更短.
- (这段也可以不看)与之前做了一个关于appdelegate文件加载不同第三方的框架,oc版本里面用到了消息转发,其中用到了这个东西forwardingTarget,找了网上的文章,又臭又长,看完以后根本没get到我想用到的功能,之后我用的swift写的把第三方模块化的框架也没用到这个方法,原因就是因为我看不懂网上的文章,太长了.但是今天我在写代码的时候用到了这个方法,并且经过简单实验,发现了我要用到的功能消息转发.
使用场景
今天要用的场景就是当我在当前类中执行一个方法的时候,如果找不到这个方法,我就让其他对象执行他里面的方法,如果看着拗口,就看下面的代码:
场景1 perform执行方法的时候
//意思就是说,如果我在当前对象里面执行了fn1(),但是没找到,我想调用其他对象里面的方法fn1()
let sel = NSSelectorFromString("fn1")
perform(sel)//但是这个方法会失败,比如没找到叫fn1的方法的时候就会调用forwardingTarget
场景2 timer运行的时候,要执行一个方法
let sel = NSSelectorFromString("fn1")
var timer = Timer.init(timeInterval: 1, target: self, selector: sel, userInfo: nil, repeats: true)
RunLoop.current.add(timer, forMode: .common)
上面2段代码本质上都是runtime调用方法fn1,第一个是直接调用,第二个是在timer里面每秒调用一次,当找不到fn1方法的时候回调用forwardingTarget方法
forwardingTarget方法的作用
格式: override func forwardingTarget(for aSelector: Selector) -> Any?
参数 aSelector: Selector,是你外面调用的方法
返回的值是你要把这个方法,给对象继续执行
下面代码的作用就是如果person对象不为空,并且person对象可以执行fn1(),就返回person对象,这样系统就会调用person对象里面的fn1()方法,否则返回nil,如果返回nil说明没找到方法,然后会崩溃,如果不想崩溃,那么需要用runtime写更多的方法才能防止崩溃,不在今天的教程范围之内
var person = Person()
override func forwardingTarget(for aSelector: Selector) -> Any? {
if person != nil && person.responds(to: aSelector) {
print("执行person对象的方法",aSelector)
return person
} else {
return nil
}
}
下面是Person类的定义,就一句话,fn1()方法的定义,里面打印了当前对象的当前方法,注意要加@objc,以为这个是oc的runtime方法,不加的话就找不到fn1
class Person: NSObject {
@objc func fn1(){
print(Self.self,#function)
}
}
demo代码下载