RunTime 大神之路
2017-04-25 10:27
155 查看
// 今天来揭开神秘的Runtime机制的面纱。希望不局限于会,最重要的是会用!!!!
先自己创建一个Dog 类
当然包含头文件哈
#import <objc/runtime.h>
#import "TestRunTime-Swift.h"
- (void)viewDidLoad {
[superviewDidLoad];
////////////////////////////改变方法的实现 //////////////////////////
// 如果 msgSend(p1,s1)不能用配置settings
enable ... objc_msgSend Calls ---NO
// objc_msgSend(self, @selector(askLog));
Method m1 =class_getInstanceMethod(self.class,@selector(askLog));
Method m2 =class_getInstanceMethod(self.class,@selector(answerLog));
method_exchangeImplementations(m1, m2);//交换两个方法的实现
objc_msgSend(self,@selector(askLog));
// swift 需要预编译一次
Animal * animal= [[Animalalloc]init];
[animal eat];
////////////////////////////// 动态添加方法 //////////////////////////
class_addMethod(animal.class,@selector(walk), (IMP)walk,"i@:");
[animal performSelector:@selector(walk)];
////////////////////////////////// 访问成员变量 //////////////////////////
unsigned count =0;
Ivar * ivars =class_copyIvarList(animal.class, &count);
for (int i =0; i < count; i ++) {
// 保护指针指向的地址不被改变,即
s可以指向其他地址,但是 s[1] = "s";不行
constchar * s =
ivar_getName(ivars[i]);
NSString * property = [NSStringstringWithCString:s
encoding:NSUTF8StringEncoding];
NSLog(@" property = %@", property);
//kvo 赋值
[animal setValue:@"tomLI"forKey:property];
}
///////////////// valueForKeyPath 和 valueForKey的区别 ////////////////////////
NSDictionary * dict =@{@"one":@"1",
@"two":@{@"three":@"23"}
};
NSLog(@"value %@",[dictvalueForKeyPath:@"two.three"]);//
可以访问到 23
NSLog(@"value %@",[dictvalueForKey:@"two.three"]);
// 访问不到 23,
NSLog(@"animal name = %@", animal.name);
// c 里面的字符串定义。 cstr是一个指针
char * cstr ="sfg";
char cstrs[12] ="234abc";
NSLog(@"cstr = %s = cstrs = %s",cstr, cstrs);
/**
* _cmd在Objective-C的方法中表示当前方法的selector,正如同self表示当前方法调用的对象实例一样。
*/
NSLog(@"_cmd %@",NSStringFromSelector(_cmd));
///////////////// 动态添加属性 ////////////////////////
self.testName =@"这是动态添加的属性";
NSLog(@"testName = %@",self.testName);
}
void walk(idself,
SEL_cmd){
NSLog(@"给动物类添加走路的方法!!");
}
void add(idself,
SEL_cmd){
NSLog(@"这是动态添加方法!");
}
- (void)askLog
{
NSLog(@"我是谁!!!");
}
- (void)answerLog
{
NSLog(@"我是你大爷");
}
static charconst * testNameKey =
"testNameKey";
- (void)setTestName:(NSString*)name
{
/*
OBJC_ASSOCIATION_ASSIGN; //assign策略
OBJC_ASSOCIATION_COPY_NONATOMIC; //copy策略
OBJC_ASSOCIATION_RETAIN_NONATOMIC; // retain策略
OBJC_ASSOCIATION_RETAIN;
OBJC_ASSOCIATION_COPY;
*/
/*
* id object 给哪个对象的属性赋值
const void *key 属性对应的key
id value 设置属性值为value
objc_AssociationPolicy policy 使用的策略,是一个枚举值,和copy,retain,assign是一样的,手机开发一般都选择NONATOMIC
objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy);
*/
objc_setAssociatedObject(self,testNameKey,
name, OBJC_ASSOCIATION_COPY_NONATOMIC);
}
- (NSString*)testName
{
return (NSString*)objc_getAssociatedObject(self,testNameKey);
}
输出:
2017-04-25 10:22:19.331 TestRunTime[2370:333381]
我是你大爷
2017-04-25 10:22:19.332 TestRunTime[2370:333381]
我在吃东西!
2017-04-25 10:22:19.332 TestRunTime[2370:333381]
给动物类添加走路的方法!!
2017-04-25 10:22:19.332 TestRunTime[2370:333381] property = name
2017-04-25 10:22:19.333 TestRunTime[2370:333381] value 23
2017-04-25 10:22:19.333 TestRunTime[2370:333381] value (null)
2017-04-25 10:22:19.333 TestRunTime[2370:333381] animal name = tomLI
2017-04-25 10:22:19.333 TestRunTime[2370:333381] cstr = sfg = cstrs = 234abc
2017-04-25 10:22:19.333 TestRunTime[2370:333381] _cmd viewDidLoad
2017-04-25 10:22:19.333 TestRunTime[2370:333381] testName =
这是动态添加的属性
先自己创建一个Dog 类
当然包含头文件哈
#import <objc/runtime.h>
#import "TestRunTime-Swift.h"
- (void)viewDidLoad {
[superviewDidLoad];
////////////////////////////改变方法的实现 //////////////////////////
// 如果 msgSend(p1,s1)不能用配置settings
enable ... objc_msgSend Calls ---NO
// objc_msgSend(self, @selector(askLog));
Method m1 =class_getInstanceMethod(self.class,@selector(askLog));
Method m2 =class_getInstanceMethod(self.class,@selector(answerLog));
method_exchangeImplementations(m1, m2);//交换两个方法的实现
objc_msgSend(self,@selector(askLog));
// swift 需要预编译一次
Animal * animal= [[Animalalloc]init];
[animal eat];
////////////////////////////// 动态添加方法 //////////////////////////
class_addMethod(animal.class,@selector(walk), (IMP)walk,"i@:");
[animal performSelector:@selector(walk)];
////////////////////////////////// 访问成员变量 //////////////////////////
unsigned count =0;
Ivar * ivars =class_copyIvarList(animal.class, &count);
for (int i =0; i < count; i ++) {
// 保护指针指向的地址不被改变,即
s可以指向其他地址,但是 s[1] = "s";不行
constchar * s =
ivar_getName(ivars[i]);
NSString * property = [NSStringstringWithCString:s
encoding:NSUTF8StringEncoding];
NSLog(@" property = %@", property);
//kvo 赋值
[animal setValue:@"tomLI"forKey:property];
}
///////////////// valueForKeyPath 和 valueForKey的区别 ////////////////////////
NSDictionary * dict =@{@"one":@"1",
@"two":@{@"three":@"23"}
};
NSLog(@"value %@",[dictvalueForKeyPath:@"two.three"]);//
可以访问到 23
NSLog(@"value %@",[dictvalueForKey:@"two.three"]);
// 访问不到 23,
NSLog(@"animal name = %@", animal.name);
// c 里面的字符串定义。 cstr是一个指针
char * cstr ="sfg";
char cstrs[12] ="234abc";
NSLog(@"cstr = %s = cstrs = %s",cstr, cstrs);
/**
* _cmd在Objective-C的方法中表示当前方法的selector,正如同self表示当前方法调用的对象实例一样。
*/
NSLog(@"_cmd %@",NSStringFromSelector(_cmd));
///////////////// 动态添加属性 ////////////////////////
self.testName =@"这是动态添加的属性";
NSLog(@"testName = %@",self.testName);
}
void walk(idself,
SEL_cmd){
NSLog(@"给动物类添加走路的方法!!");
}
void add(idself,
SEL_cmd){
NSLog(@"这是动态添加方法!");
}
- (void)askLog
{
NSLog(@"我是谁!!!");
}
- (void)answerLog
{
NSLog(@"我是你大爷");
}
static charconst * testNameKey =
"testNameKey";
- (void)setTestName:(NSString*)name
{
/*
OBJC_ASSOCIATION_ASSIGN; //assign策略
OBJC_ASSOCIATION_COPY_NONATOMIC; //copy策略
OBJC_ASSOCIATION_RETAIN_NONATOMIC; // retain策略
OBJC_ASSOCIATION_RETAIN;
OBJC_ASSOCIATION_COPY;
*/
/*
* id object 给哪个对象的属性赋值
const void *key 属性对应的key
id value 设置属性值为value
objc_AssociationPolicy policy 使用的策略,是一个枚举值,和copy,retain,assign是一样的,手机开发一般都选择NONATOMIC
objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy);
*/
objc_setAssociatedObject(self,testNameKey,
name, OBJC_ASSOCIATION_COPY_NONATOMIC);
}
- (NSString*)testName
{
return (NSString*)objc_getAssociatedObject(self,testNameKey);
}
输出:
2017-04-25 10:22:19.331 TestRunTime[2370:333381]
我是你大爷
2017-04-25 10:22:19.332 TestRunTime[2370:333381]
我在吃东西!
2017-04-25 10:22:19.332 TestRunTime[2370:333381]
给动物类添加走路的方法!!
2017-04-25 10:22:19.332 TestRunTime[2370:333381] property = name
2017-04-25 10:22:19.333 TestRunTime[2370:333381] value 23
2017-04-25 10:22:19.333 TestRunTime[2370:333381] value (null)
2017-04-25 10:22:19.333 TestRunTime[2370:333381] animal name = tomLI
2017-04-25 10:22:19.333 TestRunTime[2370:333381] cstr = sfg = cstrs = 234abc
2017-04-25 10:22:19.333 TestRunTime[2370:333381] _cmd viewDidLoad
2017-04-25 10:22:19.333 TestRunTime[2370:333381] testName =
这是动态添加的属性
相关文章推荐
- 理解C语言——从小菜到大神的晋级之路(5)——程序流程控制
- 一只“小笨鸟”的大神之路
- JAVA大神之路
- 理解C语言——从小菜到大神的晋级之路(8)——数组、指针和字符串
- 昌大软院大神养成计划之网页设计之路第六天
- Java进击之路——成为JAVA大神你必须完成的30个目标(包括核心思想,核心类库,核心技术等)
- 微信小程序开发之大神之路最全微信小程序开发教程(视频+精品文章)
- oracle菜鸟到大神之路
- 我的算法学习之路【原来还是那个大神写的 继续膜拜】
- 十大编程算法助程序员走上大神之路
- 昌大软院大神养成计划之网页设计之路第八天
- 从基础小白到业内大神,ps高手的成长之路
- 大神之路-Android优质资源和项目大整合
- 昌大软院大神养成计划之网页设计之路第一天
- 理解C语言——从小菜到大神的晋级之路(3)——C源程序的基本结构与调试方法
- 安卓开发之路----转自任玉刚大神
- 十大编程算法助程序员走上大神之路
- 昌大大神养成计划之网页设计之路第五天
- 微信小程序开发之大神之路最全微信小程序开发教程(视频+精品文章)