RunTime(绝对干货,很多面试都问它!!!)

1.RunTime的C语言的代码,可以动态修改添加删除成员变量和方法.在我下面的可以看我下面的代码
2.在程序运行中,动态的创建一个类.
在程序运行中,动态的添加一个属性/方法,动态的属性和方法,会遍历一个类的所有属性和方法.
我们所写的OC的代码终会编译成c++文件.生成.opp文件.
<对于C语言对于函数调用在编译的时候就确定了调用哪个那个函数.C语言的函数未实现就会报错.对于OC函数来说,属于动态的调用过程,在编译的时候无法确定是调用哪个函数,只有字调用的时候根据函数名去找函数.所以OC得函数只声明不实现也不会报错.在代码中我们定义了一个walkOnTheStreet

Ivar *class_copyIvarList(Class cls, unsigned int *outCount)   //获取所有成员变量
const char *ivar_getName(Ivar v)     //获取某个成员变量的名字
const char *ivar_getTypeEncoding(Ivar v)   //获取某个成员变量的类型编码
Ivar class_getInstanceVariable(Class cls, const char *name)    //获取某个类中指定名称的成员变量
id object_getIvar(id obj, Ivar ivar)    //获取某个对象中的某个成员变量的值
void object_setIvar(id obj, Ivar ivar, id value)    //设置某个对象的某个成员变量的值```

参考资料网站:TypeEncoding:https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtTypeEncodings.html#//apple_ref/doc/uid/TP40008048-CH100-SW1


void objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy) //为某个类关联某个对象
id objc_getAssociatedObject(id object, const void *key)
//获取到某个类的某个关联对象
void objc_removeAssociatedObjects(id object) //移除已经关联的对象```

建一个Person类

Person.h文件

#import <Foundation/Foundation.h>
#import "Dog.h"
@interface Person : NSObject

@property(nonatomic,copy) NSString *name;

@property(nonatomic,copy) NSString *gender;

@property(nonatomic,strong) NSNumber *age;

@property(nonatomic,assign) NSInteger weight;

@property(nonatomic,strong) Dog *dog;

+(Person *)personWithName:(NSString *)name age:(NSNumber *)age
                   gender:(NSString *)gender weight:(NSInteger)weight;

-(void)getPersonMessage;

//-(void)walkOnTheStreet:(NSString *)str;

-(void)walkOnTheStreet;```

Person.m文件

import "Person.h"

import <objc/runtime.h>

@interface Person()<NSCoding>

@end

@implementation Person

/**
void objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy) //为某个类关联某个对象
id objc_getAssociatedObject(id object, const void *key)
//获取到某个类的某个关联对象
void objc_removeAssociatedObjects(id object) //移除已经关联的对象

*/

//编码
-(void)encodeWithCoder:(NSCoder *)aCoder {
unsigned int outCount;
Ivar *ivarList = class_copyIvarList([Person class], &outCount);
for (NSInteger i = 0; i < outCount; i++ ) {

    const char *cName = ivar_getName(ivarList[i]);
    //将C语言转化为OC
    NSString *name = [NSString stringWithUTF8String:cName];
    [aCoder encodeObject:[self valueForKey:name] forKey:name];
}

}

//解码
-(instancetype)initWithCoder:(NSCoder *)aDecoder {
self = [super init];
if (self) {
unsigned int outCout;
Ivar *ivarList = class_copyIvarList([Person class], &outCout);
for (NSInteger i = 0; i < outCout; i++) {
const char *cName = ivar_getName(ivarList[i]);
NSString *name = [NSString stringWithUTF8String:cName];
[self setValue:[aDecoder decodeObjectForKey:name] forKey:name];
}
}
return self;
}

/**
Ivar *class_copyIvarList(Class cls, unsigned int *outCount) //获取所有成员变量
const char *ivar_getName(Ivar v) //获取某个成员变量的名字
const char *ivar_getTypeEncoding(Ivar v) //获取某个成员变量的类型编码
Ivar class_getInstanceVariable(Class cls, const char *name) //获取某个类中指定名称的成员变量
id object_getIvar(id obj, Ivar ivar) //获取某个对象中的某个成员变量的值
void object_setIvar(id obj, Ivar ivar, id value) //设置某个对象的某个成员变量的值
TypeEncoding:https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtTypeEncodings.html#//apple_ref/doc/uid/TP40008048-CH100-SW1
*/

-(NSString )description {
/
*
class:要获取的类名
outcount:通过这一个函数执行之后将成员变量的个数赋值到此
*/
unsigned int outCount;
//获取到所有的成员变量
Ivar *ivarList = class_copyIvarList([Person class], &outCount);
//遍历
for (NSInteger i = 0; i < outCount; i++) {
//每一次获取一个成员变量
Ivar ivar = ivarList[i];
//打印成员变量的类型和编码
NSLog(@"name= %s,type= %s",ivar_getName(ivar),ivar_getTypeEncoding(ivar));
}
return nil;
}

+(Person *)personWithName:(NSString *)name age:(NSNumber *)age
gender:(NSString *)gender weight:(NSInteger)weight {
Person * person = [[Person alloc] init];
unsigned int outCount;
Ivar *ivarList = class_copyIvarList(self, &outCount);
//obj:要设置的对象 ivar:要设置的对象的某一个属性 value:value
object_setIvar(person, ivarList[0], name);
object_setIvar(person, ivarList[1], age);
object_setIvar(person, ivarList[2], gender);
object_setIvar(person, ivarList[3], @(weight));
return person;
}

-(void)getPersonMessage {
unsigned int outCount;
Ivar *ivarList = class_copyIvarList([Person class],&outCount);
for (NSInteger i = 0; i < outCount; i++) {
NSLog(@"name = %s,value = %@",ivar_getName(ivarList[i]),object_getIvar(self, ivarList[i]));
}
}

/**
消息发送机制
1 + resolveInstanceMethod:(SEL)sel // 为一个实例方法动态添加实现

  • resolveClassMethod:(SEL)sel // 为一个类方法动态添加实现
    2 - (id)forwardingTargetForSelector:(SEL)aSelector
    //为没有实现的方法指定一个对象
    3 - (void)forwardInvocation:(NSInvocation *)anInvocation
    //子类重载这个方法为消息指定其他对象
    */

//1、为一个实例动态添加实现
//+(BOOL) resolveInstanceMethod:(SEL)sel {
// NSString selString = NSStringFromSelector(sel);
// if ([selString isEqualToString:@"walkOnTheStreet:"]) {
//动态添加实现方法
/
*
cls:类
name:没实现的方法名
IMP:要添加的实现
type:动态添加的实现类型编码
*/

// class_addMethod(self,@selector(walkOnTheStreet:), (IMP)walkFunction, "V@:@");
// }
// return [super resolveInstanceMethod:sel];
//}

void walkFunction(id self,SEL sel,NSString *str) {
NSLog(@"person----%s-----%@",func,str);

}

//切换消息转发对象,方式1
/*
-(id)forwardingTargetForSelector:(SEL)aSelector {
NSString *selString = NSStringFromSelector(aSelector);
if ([selString isEqualToString:@"walkOnTheStreet"]) {
self.dog = [[Dog alloc] init];
return self.dog;
}
return [super forwardingTargetForSelector:aSelector];
}
*/

//切换消息转发对象,方式2
-(void)forwardInvocation:(NSInvocation *)anInvocation {
if ([Dog instancesRespondToSelector:anInvocation.selector]) {
self.dog = [[Dog alloc] init];
[anInvocation invokeWithTarget:self.dog];
}
}

//给方法制定一个有效的签名
-(NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector {
NSMethodSignature *methodSignature = [super methodSignatureForSelector:aSelector];
if (!methodSignature) {
methodSignature = [Dog instanceMethodSignatureForSelector:aSelector];
}
return methodSignature;
}```
创建一个字典的类目
NSDictionary+Mydic.h文件

#import <Foundation/Foundation.h>

@interface NSDictionary (Mydic)

@property(nonatomic,strong) NSString *name;

@end```
NSDictionary+Mydic.m文件

import "NSDictionary+Mydic.h"

import <objc/runtime.h>

@implementation NSDictionary (Mydic)

/*
void objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy) //为某个类关联某个对象
id objc_getAssociatedObject(id object, const void *key)
//获取到某个类的某个关联对象
void objc_removeAssociatedObjects(id object) //移除已经关联的对象
*/
-(void)setName:(NSString *)name {
//object:要关联的对象 key:成员变量对应的key ,@selector(属性名) value:value
objc_setAssociatedObject(self ,@selector(name), name,OBJC_ASSOCIATION_COPY_NONATOMIC);
}

-(NSString *)name {
return objc_getAssociatedObject(self, @selector(name));
}

@end```

建一个dog类
Dog.h文件

#import <Foundation/Foundation.h>

@interface Dog : NSObject

-(void)walkOnTheStreet;

@end```
Dog.m文件

import "Dog.h"

@implementation Dog

-(void)walkOnTheStreet {
NSLog(@"dog----%s",func);
}

@end```

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,588评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,456评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,146评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,387评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,481评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,510评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,522评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,296评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,745评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,039评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,202评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,901评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,538评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,165评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,415评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,081评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,085评论 2 352

推荐阅读更多精彩内容