OC的消息機(jī)制,會(huì)經(jīng)常在面試中被問(wèn)到,所以這里記錄一下,
消息發(fā)送
首先會(huì)判斷receiver 是否為nil,假如為nil,那么就什么也不做,假如不為nil,那么就會(huì)去receiverClass的方法緩存里面查找方法,假如找到了就會(huì)調(diào)用方法,假如找不到,就會(huì)去receiverClass的方法列表中查找方法,假如也找不到,就去superClass的方法緩存中查找,也沒(méi)找到,就會(huì)去superClass的方法列表里面找,直到一直找到了基類也沒(méi)有找到,那么它就會(huì)開始動(dòng)態(tài)方法解析,假如中間哪一步找到了方法,那么就會(huì)調(diào)用方法,結(jié)束查找,并把方法緩存到receiverClass的方法緩存中去

動(dòng)態(tài)解析
首先會(huì)判斷是否動(dòng)態(tài)解析過(guò),假如已經(jīng)動(dòng)態(tài)解析過(guò)了,那么就會(huì)進(jìn)入消息轉(zhuǎn)發(fā)階段,假如沒(méi)有,那么就會(huì)調(diào)用+resolveInstanceMethod:或者 +resolveClassMethod:方法,開發(fā)者可以實(shí)現(xiàn)這兩個(gè)方法來(lái)達(dá)到動(dòng)態(tài)添加方法實(shí)現(xiàn)的目的,調(diào)用完方法之后,會(huì)標(biāo)記為已經(jīng)動(dòng)態(tài)解析過(guò)了,并會(huì)重新走“消息發(fā)送”流程,從receiverClass的緩存中查找方法這一步開始執(zhí)行。

消息轉(zhuǎn)發(fā)
首先會(huì)調(diào)用forwardingTargetForSelector:方法,假如不為nil, 那么就會(huì)拿到返回值,調(diào)用objc_msgSend(返回值,SEL),假如返回值為nil,那么就會(huì)調(diào)用methodSignatureForSelector:,假如methodSignatureForSelector:返回值不為nil,就會(huì)調(diào)用forwardInvocation:方法,開發(fā)者可以在這個(gè)方法中自定義任何邏輯,假如返回值為nil,那就會(huì)調(diào)用doesNotRecognizeSelector:方法,
forwardingTargetForSelector:與methodSignatureForSelector:有對(duì)象方法和類方法兩個(gè)版本,可根據(jù)開發(fā)需要,自行選擇。
