多態:相同接口,不同實現 相同接口:方法的簽名、參數、返回值相同 不同實現:具體實現的內容不同
動態多態包括:
動態類型識別動態綁定動態加載
typedef id(*IMP)(id, SEL,...)@autoreleasepool{Person *a = [[Person alloc] init];[a PRint];SEL act = @selector("print");//act得到print的SEL//或者 SEL act = NSSelectorFromString(@"print");從字符串獲得方法的SEL//或者NSSring * name = NSStringFromSelector(act);從const char * sn = sel_getName(act);//用SEL做參數,找到指定的方法,并取得其首地址a.name = @"tom";NSLog(@"%s",sn);IMP p = [a methodForSelector:act];p(a, act);//p就相當于*IMP【typedef id(*IMP)】(id, SEL,...),a相當于self,act即為SELfor (int i=0; i<10000; i++){ //[a print]; p(a, act); }//在循環次數很多的情況下,如果用第一種方法,消息傳遞的方法名尋找過程很耗費時間,所以如果改進為第二種方法,可以節省很多時間}class-object類對象的寫法:[類名或者對象名 class]
-(BOOL)isKindOf:class-object//對象是不是class-object或者其子類的成員-(BOOL)isMemberOfClass:class-object//對像是不是class-object的成員if([object isMemberOf:[someClass class]])//判定是否為某個類的實例對象+(BOOL)isSubclassOfClass:class-object//對象是指定類的子類嗎等號右邊selector的寫法:@selector(方法名、@“字符串”)
-(BOOL)respondToSelector:selector//對象是否能響應selector所指定的方法+(BOOL)instancesRespondToSelector:selector//指定的類對象是否能響應selector消息派發:oc中消息一直到運行時才能綁定到對應的方法
[receiver message];轉換成函數 objc_msgSend(receiver, selector); 其中receivier賦值給self, selector就是方法選擇器
如果消息是 [super message];
為了加快消息處理,運行時會緩存映射表,在每個類中查找方法會先在緩存中找,如果找不到再到方法映射表中去找
oc允許在運行時加載一個新類,或給已有的類加載新的方法 只需要四步 1. #import 《objc/runtime.h> 2. 為class pair分配空間 3. 增加方法(class_addMethod)或者實例變量(class_addlvar) 4. 注冊新類
#import<objc/runtime.h>//注意引入void sayHello(id self,SEL_cnd,NSString* aHello){ NSLog(@"%@",aHello);}//-(void)sayHello:(NSString*)aHello;上面函數就時這個方法的等價寫法//void(*)(id self, SEL_cnd,NSString*);可以看出每個方法都有self和SEL兩個隱含參數@autoreleasepool{ Class parentClass=[NSObject class]; Class newClass=objc_allocateClassPair(parentClass,"ASNewClass",0);//為class pair分配空間 Class_addMethod(newClass,@selector(sayHello:),(IMP)sayHello,"v@:@"); //增加方法(class_addMethod)或者實例變量(class_addlvar) objc_registerClassPair(newClass);//注冊新類 id p = [[newClass alloc] init]; if([p respondsToSelector:@selector(sayHello:)]){ [p performSelector:@selector(sayHello:) withObject:@"hello world!"]; } }新聞熱點
疑難解答