美文网首页
Runtime初识

Runtime初识

作者: ZYZZZ | 来源:发表于2016-07-28 21:19 被阅读0次

runtime的使用先导入runtime类

#import <objc/runtime.h>

runtime 可以对类操作
举个例子
先创建一个Person类
在.h中声明方法

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

在.m中使用

#import "Person.h"
#import <objc/runtime.h>

@implementation Person
/*
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", ivar_getName(ivar));
        NSLog(@"type = %s", ivar_getTypeEncoding(ivar));
        
    }
    return nil;
}

+ (Person *)personWithName:(NSString *)name gender:(NSString *)gender age:(NSNumber *)age weight:(NSInteger)weight
{
    Person *person = [Person new];
    unsigned int outCount;
    Ivar *ivarList = class_copyIvarList(self, &outCount);
    // obj:要设置的对象  ivar:要设置的对象的某一个属性value:value
    object_setIvar(person, ivarList[0], name);
    object_setIvar(person, ivarList[1], gender);
    object_setIvar(person, ivarList[2], age);
    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]));
    }
}

// 编码
- (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]);
        NSString *name = [NSString stringWithUTF8String:cName];
        
        [aCoder encodeObject:[self valueForKey:name] forKey:name];
    
    }
}

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

/*
+ (BOOL)resolveInstanceMethod:(SEL)sel
{
    NSString *selString = NSStringFromSelector(sel);
    if ([selString isEqualToString:@"walkOnTheStreet:"]) {
        // 为一个没有实现的方法动态添加实现
 
         cls:类
         name:没有实现的方法名
         IMP:要添加的实现
         types:动态添加的实现的类型编码
 
        class_addMethod(self, @selector(walkOnTheStreet:), (IMP)walkFunc, "V@:@");
    }
    return [super resolveInstanceMethod:sel];
}
*/
void walkFunc(id self, SEL sel, NSString *str){
    NSLog(@"Person -- %s, %@", __func__, str);
}

// 切换消息转换对象 方式一

/*
- (id)forwardingTargetForSelector:(SEL)aSelector
{
    NSString *selString = NSStringFromSelector(aSelector);
    if ([selString isEqualToString:@"walkOnTheStreet:"]) {
        self.dog = [Dog new];
        return self.dog;
        
    }
    else {
        return [super forwardingTargetForSelector:aSelector];
    }
}
*/

- (void)forwardInvocation:(NSInvocation *)anInvocation
{
    if ([Dog instancesRespondToSelector:anInvocation.selector]) {
        self.dog = [Dog new];
        [anInvocation invokeWithTarget:self.dog];
    }
}

// 给方法制定一个有效的签名
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector
{
    NSMethodSignature *methodSignature = [super methodSignatureForSelector:aSelector];
    if (!methodSignature) {
        methodSignature = [Dog instanceMethodSignatureForSelector:aSelector];
    }
    return methodSignature;
}

runtime在类目中的使用

/* 
 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 {
    // objc:要关联的对象 key:成员变量对应的key值,@selector(属性名)value:value
    objc_setAssociatedObject(self, @selector(name), name, OBJC_ASSOCIATION_COPY_NONATOMIC);
}

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

相关文章

  • 初识Runtime

    最近想深入学习一下 runtime 看了比较多的博客和文档,但是好多博主上来就开始讲 runtime 的原理、消息...

  • Runtime初识

    Runtime 运行时,是一套底层的 C 语言 API,其为 iOS 内部的核心之一,我们平时编写的 OC 代码,...

  • 初识 Runtime

  • runtime 初识

    我们随便写一个小程序,代码如下: person类头文件如下, #import@interfacePerson : ...

  • 初识RunTime

    初次接触RunTime,记录下自己的学习心得,为后来者铺平道路,提供一个学习的切入点。 首先简单的介绍下RunTi...

  • Runtime初识

    runtime的使用先导入runtime类 runtime 可以对类操作举个例子先创建一个Person类在.h中声...

  • 初识runtime

    runtime是什么? runtime是一个c和汇编写的动态库,它就像一个小小的系统,将OC和C紧密关联,这个系统...

  • 初识runtime

    大家都知道OC是动态语言,其主要特征就是动态绑定,消息转发。我们在调用NS方法的时候,runtime其实就已经在背...

  • runTime初识

    这里就不说runtime有多牛逼了。直接进入正题。 首先Objective-C是面向对象的,任何类的定义都是对象。...

  • 初识runtime

    算算代码写了一段时间,从去年的6月份到今年的11月.从一个毛头小子,碰见问题只能选择求助,到现在能独立处理问题.我...

网友评论

      本文标题:Runtime初识

      本文链接:https://www.haomeiwen.com/subject/pynajttx.html