在對象上調用方法是OC中經常使用的功能。用OC的屬于說,叫做“傳遞消息”。消息有“名稱”(name) 或 “選擇子” (selector), 可以接受參數(shù),而且可能還有返回值。
1.一個參數(shù)+多個參數(shù)的形式: [receiver message]
// 單個參數(shù)
objc_msgSend(receiver, selector)
// 多個參數(shù)
objc_msgSend(receiver, selector, arg1, arg2, …);
特殊情況:
- objc_msgSend_stret:如果待發(fā)送的消息要返回結構體,那么可交由此函數(shù)處理。
- objc_msgSend_fpret:如果消息返回的是浮點數(shù),那么交由此函數(shù)處理。
- objc_msgSendSuper:如果要給超類發(fā)消息,例如[super message:parameter],那么就交由此函數(shù)處理。
2.基本知識:
(1)首先通過第一個參數(shù)的receiver,找到它的isa 指針,然后在isa 指向的Class 對象中使用第二個參數(shù)selector 查找方法;
(2)如果沒有找到,就使用當前Class 對象中的新的isa 指針到上一級的父類的Class 對象中查找;
(3)當找到方法后,再依據(jù)receiver 的中的self 指針找到當前的對象,調用當前對象的具體實現(xiàn)的方法(IMP),然后傳遞參數(shù),調用實現(xiàn)方法。
(4)假如一直找到NSObject 的Class 對象,也沒有找到你調用的方法,就會報告不能識別發(fā)送消息的錯誤。
3.具體項目中的使用:
(1)導入頭文件:
#import <objc/runtime.h>
#import <objc/message.h>
(2)使用objc_msgSend調用函數(shù):
-(voidtest{
NSLog(@"test———objc_msgSend");
}
//使用前
[self test];
//使用后
SEL testFunc = NSSelectorFromString(@"test");
((void(*)(id,SEL, id,id))objc_msgSend)(self, testFunc, nil, nil);
(3)使用objc_msgSend方法的好處:為了減少各自模塊之前的耦合度,實現(xiàn)分離
要點:
- 消息由接收者、選擇器及參數(shù)構成。給某對象“發(fā)送消息”(invoke a message)也就相當于在該對象上“調用方法”(call a method)。
- 發(fā)給某對象的全部信息都要由“動態(tài)消息派發(fā)系統(tǒng)”(dynamic message dispatch system)來處理,該系統(tǒng)會查出對應的方法,并執(zhí)行其代碼。