依照惯例跳过Runtime的介绍,这里只介绍Runtime的基本用法和简单应用例子。
一、获取属性列表
-(void)getPropertyList
{
NSLog(@"----------获取属性列表----------");
unsigned int count;
objc_property_t *propertyList = class_copyPropertyList([self class], &count);
for (NSInteger i = 0 ; i < count; i ++) {
const char * name = property_getName(propertyList[i]);
NSLog(@"%@",[NSString stringWithUTF8String:name]);
}
}
输出结果:
**2016-03-03 10:09:14.529 FL_RUNTIME_DEMO[11547:4314954] ----------****获取属性列表****----------**
**2016-03-03 10:09:14.530 FL_RUNTIME_DEMO[11547:4314954] publicString**
**2016-03-03 10:09:14.530 FL_RUNTIME_DEMO[11547:4314954] inPrivateString**
二、获取变量列表
-(void)getIvarList
{
NSLog(@"----------获取变量列表----------");
unsigned int count;
Ivar *ivarList = class_copyIvarList([self class], &count);
for (NSInteger i = 0 ; i < count; i ++) {
const char * name = ivar_getName(ivarList[i]);
NSLog(@"%@",[NSString stringWithUTF8String:name]);
}
}
输出结果:
**2016-03-03 10:12:39.179 FL_RUNTIME_DEMO[11584:4318809] ----------****获取变量列表****----------**
**2016-03-03 10:12:39.180 FL_RUNTIME_DEMO[11584:4318809] privateString**
**2016-03-03 10:12:39.180 FL_RUNTIME_DEMO[11584:4318809] _publicString**
**2016-03-03 10:12:39.180 FL_RUNTIME_DEMO[11584:4318809] _inPrivateString**
这里获取的是变量列表,注意_publicString
和_inPrivateString
也是变量
三、获取实例方法列表
-(void)getMethodList
{
NSLog(@"----------获取实例方法列表----------");
unsigned int count;
Method *methodList = class_copyMethodList([self class], &count);
for (NSInteger i = 0 ; i < count; i ++) {
SEL name = method_getName(methodList[i]);
NSLog(@"%@",NSStringFromSelector(name));
}
}
输出结果:
**2016-03-03 10:17:02.123 FL_RUNTIME_DEMO[11612:4323650] ----------****获取方法列表****----------**
**2016-03-03 10:17:02.124 FL_RUNTIME_DEMO[11612:4323650] getMethodList**
**2016-03-03 10:17:02.124 FL_RUNTIME_DEMO[11612:4323650] testMethodOne**
**2016-03-03 10:17:02.125 FL_RUNTIME_DEMO[11612:4323650] testMethodTwo**
**2016-03-03 10:17:02.125 FL_RUNTIME_DEMO[11612:4323650] getPropertyList**
**2016-03-03 10:17:02.125 FL_RUNTIME_DEMO[11612:4323650] getIvarList**
**2016-03-03 10:17:02.125 FL_RUNTIME_DEMO[11612:4323650] getProtocolList**
**2016-03-03 10:17:02.125 FL_RUNTIME_DEMO[11612:4323650] getClassMethod**
**2016-03-03 10:17:02.125 FL_RUNTIME_DEMO[11612:4323650] testMsgSend**
**2016-03-03 10:17:02.125 FL_RUNTIME_DEMO[11612:4323650] testAssociatedObject**
**2016-03-03 10:17:02.126 FL_RUNTIME_DEMO[11612:4323650] testDicToModel**
**2016-03-03 10:17:02.126 FL_RUNTIME_DEMO[11612:4323650] testMethod**
**2016-03-03 10:17:02.126 FL_RUNTIME_DEMO[11612:4323650] testCategory**
**2016-03-03 10:17:02.126 FL_RUNTIME_DEMO[11612:4323650] testMethodRepost**
**2016-03-03 10:17:02.126 FL_RUNTIME_DEMO[11612:4323650] publicString**
**2016-03-03 10:17:02.126 FL_RUNTIME_DEMO[11612:4323650] setPublicString:**
**2016-03-03 10:17:02.215 FL_RUNTIME_DEMO[11612:4323650] inPrivateString**
**2016-03-03 10:17:02.215 FL_RUNTIME_DEMO[11612:4323650] setInPrivateString:**
**2016-03-03 10:17:02.215 FL_RUNTIME_DEMO[11612:4323650] .cxx_destruct**
**2016-03-03 10:17:02.215 FL_RUNTIME_DEMO[11612:4323650] forwardInvocation:**
**2016-03-03 10:17:02.216 FL_RUNTIME_DEMO[11612:4323650] methodSignatureForSelector:**
**2016-03-03 10:17:02.216 FL_RUNTIME_DEMO[11612:4323650] forwardingTargetForSelector:**
**2016-03-03 10:17:02.216 FL_RUNTIME_DEMO[11612:4323650] viewDidLoad**
四、获取类方法列表
-(void)getClassMethod
{
NSLog(@"----------获取类方法列表----------");
unsigned int count;
Method *methodList = class_copyMethodList(objc_getMetaClass(class_getName([self class])), &count);
for (NSInteger i = 0 ; i < count; i ++) {
SEL name = method_getName(methodList[i]);
NSLog(@"%@",NSStringFromSelector(name));
}
}
输出结果:
**2016-03-03 10:20:31.711 FL_RUNTIME_DEMO[11661:4326710] ----------****获取类方法列表****----------**
**2016-03-03 10:20:31.712 FL_RUNTIME_DEMO[11661:4326710] testClassMethod**
**2016-03-03 10:20:31.712 FL_RUNTIME_DEMO[11661:4326710] resolveInstanceMethod:**
五、获取协议列表
-(void)getProtocolList
{
NSLog(@"----------获取协议列表----------");
unsigned int count;
Protocol * __unsafe_unretained * protocolList =class_copyProtocolList([super class], &count);
for (NSInteger i = 0 ; i < count; i ++) {
const char* name = protocol_getName(protocolList[i]);
NSLog(@"%@",[NSString stringWithUTF8String:name]);
}
}
输出结果:
**2016-03-03 10:21:45.912 FL_RUNTIME_DEMO[11703:4328231] ----------****获取协议列表****----------**
**2016-03-03 10:21:45.914 FL_RUNTIME_DEMO[11703:4328231] UITableViewDataSource**
**2016-03-03 10:21:45.914 FL_RUNTIME_DEMO[11703:4328231] UITableViewDelegate**
六、消息发送
@interface myObject : NSObject
@property(strong,nonatomic)NSString *name;
@property(assign,nonatomic)NSInteger uid;
-(void)testMyObject;
@end
@implementation myObject
-(void)testMyObject
{
NSLog(@"测试成功");
}
}
@end
.
.
.
-(void)testMsgSend
{
NSLog(@"----------测试向对象发送消息----------");
myObject *my = [[myObject alloc] init];
objc_msgSend(my,@selector(testMyObject));
}
输出结果:
**2016-03-03 10:25:59.154 FL_RUNTIME_DEMO[11744:4332809] ----------****测试向对象发送消息****----------**
**2016-03-03 10:25:59.155 FL_RUNTIME_DEMO[11744:4332809] ****测试成功**
七、关联对象
-(void)testAssociatedObject
{
NSLog(@"----------测试关联对象----------");
const char * key = "thekey";
NSString *mykey = objc_getAssociatedObject(self, key);
if (!mykey) {
objc_setAssociatedObject(self, key, @"123",OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
NSString *getkey = objc_getAssociatedObject(self, key);
NSLog(@"%@",getkey);
}
输出结果:
**2016-03-03 10:29:24.214 FL_RUNTIME_DEMO[11788:4336028] ----------****测试关联对象****----------**
**2016-03-03 10:29:24.216 FL_RUNTIME_DEMO[11788:4336028] 123**
八、字典转模型
-(void)testDicToModel
{
NSLog(@"----------测试字典转模型----------");
NSDictionary *dic = @{@"name":@"jack",@"uid":@123};
myObject *my = [[myObject alloc] init];
[dic enumerateKeysAndObjectsUsingBlock:^(NSString *key, NSString *value, BOOL * stop) {
//获得属性对象
objc_property_t property = class_getProperty([my class], key.UTF8String);
//获取属性名称
NSString *propertyName = [NSString stringWithUTF8String:property_getName(property)];
//获得属性attr
// const char * attr = property_getAttributes(property);
// NSString *attrs = [NSString stringWithUTF8String:attr];
//设置对应属性对应值
[my setValue:value forKey:propertyName];
}];
NSLog(@"name = %@,uid = %ld",my.name,my.uid);
}
输出结果:
**2016-03-03 10:31:54.336 FL_RUNTIME_DEMO[11819:4338148] ----------****测试字典转模型****----------**
**2016-03-03 10:31:54.337 FL_RUNTIME_DEMO[11819:4338148] name = jack,uid = 123**
九、method相关函数
-(void)testMethodOne
{
NSLog(@"这是函数1");
}
-(void)testMethodTwo
{
NSLog(@"这是函数2");
}
-(void)testMethod
{
NSLog(@"----------测试method相关函数----------");
Method method1 = class_getInstanceMethod([self class], @selector(testMethodOne));
Method method2 = class_getInstanceMethod([self class], @selector(testMethodTwo));
method_exchangeImplementations(method1, method2);
NSLog(@"调用methodOne输出:");
[self testMethodOne];
NSLog(@"调用methodTwo输出:");
[self testMethodTwo];
IMP imp = method_getImplementation(method1);
method_setImplementation(method2, imp);
NSLog(@"重新设置method2的imp后调用methodTwo输出:");
[self testMethodTwo];
NSLog(@"这时method1的输出是:");
[self testMethodOne];
BOOL isequal = sel_isEqual(method_getName(method1), method_getName(method2));
NSLog(@"是否相同:%d",isequal);
}
输出结果:
**2016-03-03 10:33:42.975 FL_RUNTIME_DEMO[11857:4340224] ----------****测试****method****相关函数****----------**
**2016-03-03 10:33:42.976 FL_RUNTIME_DEMO[11857:4340224] ****调用****methodOne****输出****:**
**2016-03-03 10:33:42.976 FL_RUNTIME_DEMO[11857:4340224] ****这是函数****2**
**2016-03-03 10:33:42.977 FL_RUNTIME_DEMO[11857:4340224] ****调用****methodTwo****输出****:**
**2016-03-03 10:33:42.977 FL_RUNTIME_DEMO[11857:4340224] ****这是函数****1**
**2016-03-03 10:33:42.977 FL_RUNTIME_DEMO[11857:4340224] ****重新设置****method2****的****imp****后调用****methodTwo****输出:**
**2016-03-03 10:33:42.977 FL_RUNTIME_DEMO[11857:4340224] ****这是函数****2**
**2016-03-03 10:33:42.977 FL_RUNTIME_DEMO[11857:4340224] ****这时****method1****的输出是:**
**2016-03-03 10:33:42.977 FL_RUNTIME_DEMO[11857:4340224] ****这是函数****2**
**2016-03-03 10:33:42.977 FL_RUNTIME_DEMO[11857:4340224] ****是否相同:****0**