iOS开发笔记(4)---- 反射
来源:互联网 发布:下象棋软件 编辑:程序博客网 时间:2024/04/29 05:48
反射的强大之处在于,我们可以将对象与依赖对象之间完全解耦,创建对象可以不引用头文件,操作属性、方法可以不依赖于对象,操作对象可以不依赖于类型,操作类型可以不依赖于引用等等等等。最直观的效果是,即使不引用头文件亦可操作类型、对象及对应属性与方法。
借助强大的runtime特性,在iOS平台上我们也得以实现反射。
//使用前需要先引用runtime头文件#import <objc/runtime.h>
在这里,我们创建一个示例类型IPZClassOne
并声明四个有代表性的方法。
@interface IPZClassOne : NSObject+ (void) classMethod; //类型方法+ (IPZClassOne*) getSingleLeton; //单例- (void) instanceMethod; //实例方法- (void) onFinshedHandler:(NSString *) completeHandler;//含参数方法@end
类型反射
获取类型分为两种,通过对象获取和通过类型名称获取。
- 通过对象获取:
Class class = [self class];
- 通过名称获取:
Class class=NSClassFromString(@"IPZClassOne");
这里需要注意的是,如果名称错误或者该类型不存在的话也会有可能类型反射失败。
类型获取成功时如下图:
类型获取失败时如下图:
类型是一种特殊的对象,从图中可以看出党获取类型失败时类型对象地址为0x0,因此我们可以通过该对象的地址来判断是否获取成功。
if(class==0x0){ NSLog(@"Class Unfound"); }
实例化对象
在iOS中实例化对象的方法同样有两种:单例或者init方法。
- init方法实例化对象
id instance=[[class alloc] init];
- 单例方法实例化对象
SEL classSelector=NSSelectorFromString(@"getSingleLeton");//classSelector=@selector(getSingleLeton);if ([class respondsToSelector:classSelector]) { id instance= [class performSelector:classSelector];}
单例实现中上面这种调用selector的方法是比较安全的方法,在此之外还有一种直接调用的方法,即:
id instance=[class getSingleLeton];
然而直接使用的话编译器会报未找到该方法: No known class method for selector ‘getSingleLeton’,此种情况只需声明或定义一个同名称空方法即可
通过反射到的类型实例化对象同样有失败的可能,判断成功或失败的方法同上。
方法调用
上面已经讲了单例亦即类型方法的调用,实例对象的调用方法与之相同。
SEL instanceSelector=NSSelectorFromString(@"instanceMethod");instanceSelector=@selector(instanceMethod);if ([instance respondsToSelector:instanceSelector]) { [instance performSelector:instanceSelector];}以及: [instance instanceMethod];
然而,performSelector这种方式只能调用无参方法,有参方法仍需直接调用。
在直接调用方法之前,我们可以声明一个协议。
@protocol IPZCLassOne@optional+(void) classMethod;+(id) getSingleLeton; //返回值为id-(void) instanceMethod;-(void) onFinshedHandler:(id) completeHandler;//参数声明为id@end
此外,我们还可以通过反射在运行时获取实例方法列表及其内容。(类型方法列表无法获取,只能根据名称获取单个方法)
获取实例方法:
u_int count;Method* methods=class_copyMethodList(class, &count);//获取所有实例方法for (int i = 0; i < count ; i++){ SEL instanceSelector=method_getName(methods[i]);//获取实例方法selector const char* methodName =sel_getName(instanceSelector);//获取方法名,类似还有获取方法实现等 } free(methods);
属性获取
u_int count;objc_property_t* properties = class_copyPropertyList(class, &count);//获取属性列表NSMutableArray* propertyArray = [NSMutableArray arrayWithCapacity:count];for (int i = 0; i < count ; i++){ const char* propertyName = property_getName(properties[i]);//获取属性名称 [propertyArray addObject:[NSString stringWithCString:propertyName encoding:NSUTF8StringEncoding]];}free(properties);for (NSString *name in propertyArray){ NSString* value = [self valueForKey:name];//获取属性值}
- iOS开发笔记(4)---- 反射
- [IOS 开发] 反射
- ios开发笔记(4)
- iOS 开发--Objective-C 反射机制---(正好需要)
- iOS 开发笔记(线程)
- ios开发笔记(一)
- ios 开发笔记(一)
- iOS 开发笔记(一)
- iOS开发笔记(1)
- iOS开发笔记(2)
- iOS 程序开发个人笔记(一)ios开发简述
- iOS学习笔记08--Objective-C反射
- iOS学习笔记48-Swift(八)反射
- IOS开发反射和动态调用总结
- iOS开发—巧用反射机制
- iOS开发技巧系列 使用Swift反射
- iOS开发:Object-C的反射机制
- iOS 开发--Objective-C 反射机制
- 网络攻击技术开篇——SQL Injection
- CODEVS1033
- Android Context完全解析,你所不知道的Context的各种细节
- System Generator学习笔记(二)
- 2029 Palindromes _easy version
- iOS开发笔记(4)---- 反射
- 2015-07-12到2015-07-23小结
- 009语音识别-华为机试题目
- 模式分类2--判别函数
- crossApp初级-开发环境-1
- NYOJ-97兄弟郊游问题
- ExtJS3 简单主页面 构
- 股票学习(K线分析)
- 单向链表