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```