前言
最近在看Effective Objective-C 2.0這本書粉私,在介紹消息轉(zhuǎn)發(fā)機制這部分的時候惫谤,遇到了NSInvocation這個類壁顶。
蘋果給的官方解釋是:NSInvocation作為對象呈現(xiàn)的Objective-C消息。
An Objective-C message rendered as an object.
NSInvocation objects are used to store and forward messages between objects and between applications, primarily by NSTimer objects and the distributed objects system. An NSInvocation
object contains all the elements of an Objective-C message: a target, a selector, arguments, and the return value. Each of these elements can be set directly, and the return value is set automatically when the NSInvocation object is dispatched.
一個NSInvocation對象包含一個Objective-C消息的所有元素:target溜歪,selector若专,argument和return value『恚可以直接設(shè)置每個元素调衰,并且在NSInvocation分派對象時自動設(shè)置返回值膊爪。
所謂的方法簽名,即方法所對應(yīng)的返回值類型和參數(shù)類型嚎莉。當NSInvocation被調(diào)用米酬,它會在運行時通過目標對象去尋找對應(yīng)的方法,從而確保唯一性趋箩,可以用[receiver message]來解釋淮逻。實際開發(fā)過程中直接創(chuàng)建NSInvocation的情況不多見,這些事情通常交給系統(tǒng)來做阁簸。比如bang的JSPatch中arm64方法替換的實現(xiàn)就是利用runtime消息轉(zhuǎn)發(fā)最后一步中的NSInvocation實現(xiàn)的爬早。
NSInvocation的一般用法
以下面字符串拼接為例,我們來嘗試將該方法的調(diào)用轉(zhuǎn)換為NSInvocation的消息轉(zhuǎn)發(fā)启妹。
NSString *string = @"Hello";
NSString *addString = [string stringByAppendingString:@" World!"];
用NSInvocation轉(zhuǎn)換后:
NSString *string = @"Hello";
void* addString;
NSString* stringToAppend = @" World!";
//invocationWithMethodSignature: 使用給定方法簽名來構(gòu)建消息的對象筛严。
NSMethodSignature *signature = [string methodSignatureForSelector:@selector(stringByAppendingString:)];
NSInvocation* invocation = [NSInvocation invocationWithMethodSignature:signature];
//設(shè)置target
invocation.target = string;
invocation.selector = @selector(stringByAppendingString:);
//設(shè)置參數(shù)即上面對應(yīng)的World!字符串饶米,index為2 是因為0桨啃、1兩個參數(shù)已經(jīng)被target和selector占用
[invocation setArgument:&stringToAppend atIndex:2];
//執(zhí)行制定對象的指定方法,并且傳遞指定的參數(shù)
[invocation invoke];
//得到返回值 并賦值addString
if (signature.methodReturnLength > 0) {
[invocation getReturnValue:&addString];
NSString *str = (__bridge NSString *)addString;
NSLog(@"%@",str);
}
一般是通過NSInvocation進行消息轉(zhuǎn)發(fā)來實現(xiàn)未定義的方法檬输,通過runtime來實現(xiàn)消息的動態(tài)發(fā)送照瘾。
之后對NSInvocation的研究再在下面補充!