IOS開發反射和動態調用總結
來源:程序員人生 發布時間:2015-05-22 08:14:32 閱讀次數:2999次
和java1樣,Object-C也提供了反射的機制。
每個類都有1個Class,獲得Class有以下3種方法。
// insert code here...
//通過字符串獲得class
Class clazz = NSClassFromString(@"NSString");
NSLog(@"clazz的類型是%@",clazz);
//直接用calzz 來創建對象
id str = [[clazz alloc] init];
//通過對象來獲得class
NSLog(@"%@",[str class]);
//通過類來獲得class
NSLog(@"%d",clazz==NSString.class);
NSLog(@"Hello, World!");
/**
2015-04⑵8 17:03:18.907 反射[1322:303] clazz的類型是NSString
2015-04⑵8 17:03:19.279 反射[1322:303] __NSCFConstantString
2015-04⑵8 17:03:19.280 反射[1322:303] 1
2015-04⑵8 17:03:19.281 反射[1322:303] Hello, World!
Program ended with exit code: 0
打印出來的結果是這樣,_NSString只是類簇的前端而已
**/
對與第1種和第2種方式,都是根據類獲得Class對象,比較之下,第1種代碼安全性更高,程序再編譯階段就能夠檢測所需要訪問的Class是不是存在。性能更高,由于無需調用方法。
動態調用的方法以下。直接上代碼
#import <Foundation/Foundation.h>
@interface JQCar : NSObject
@end
#import "JQCar.h"
#import <objc/message.h>
@implementation JQCar
- (void)move:(NSNumber*)count{
int num = [count intValue];
for (int i=0; i<num; i++) {
NSLog(@"%@",[NSString stringWithFormat:@"汽車正在路上行走%d",i]);
}
}
- (double)addSpeed:(double)factor{
//動態調用move方法
//使用performSelector動態調用move方法
[self performSelector:@selector(move:) withObject:[NSNumber numberWithInt:2]];
[self performSelector:NSSelectorFromString(@"move:") withObject:[NSNumber numberWithInt:2]];
//使用objc_msgSend()函數動態調用
objc_msgSend(self,@selector(move:),[NSNumber numberWithInt:2]);
objc_msgSend(self, NSSelectorFromString(@"move:"),[NSNumber numberWithInt:3]);
NSLog(@"正在加速%g",factor);
return 100*factor;
}
@end
使用objc_msgSend可能報錯
//objc_msgSend()報錯Too many arguments to function call ,expected 0,have3
解決方法
//Build Setting--> Apple LLVM 6.0 - Preprocessing--> Enable Strict Checking of objc_msgSend Calls 改成 NO
#import <Foundation/Foundation.h>
#import <objc/message.h>
#import "JQCar.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
// insert code here...
//獲得JQCar類
Class clazz = NSClassFromString(@"JQCar");
//動態創建car
id car = [[clazz alloc] init];
//使用performSelector方法來動態調用
[car performSelector:@selector(addSpeed:) withObject:[NSNumber numberWithLong:2]];
//使用Objec_send來動態調用
objc_send(car,@selector(addSpeed:),3.4);
//定義函數指針變量
double (*addSpeed)(id ,SEL,double);
//獲得car對象的addSpeed方法,再把addSpeed方法賦值給addSpeed指針變量
addSpeed = (double (*)(id,SEL,double))[car methodForSelector:NSSelectorFromString(@"addSpeed:")];
//調用addSpeed
double speed = addSpeed(car, @selector(addSpeed:), 3.4);
NSLog(@"加速后的速度是%g",speed);
NSLog(@"Hello, World!");
}
return 0;
}
生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈