运行时- 关联

关联

- 关联是指把两个对象相互关联起来,使得其中的一个对象作为另外一个对象的一部分。
- 关联特性只有在Mac OS X V10.6以及以后的版本上才是可用的。
- 关联是基于关键字的,因此,我们可以为任何对象增加任意多的关联,每个都使用不同的关键字即可。
- 关联是可以保证被关联的对象在关联对象的整个生命周期都是可用的(在垃圾自动回收环境下也不会导致资源不可回收)。

- 关联策略表明了相关的对象是通过赋值,保留引用还是复制的方式进行关联的;还有这种关联是原子的还是非原子的。这里的关联策略和声明属性时的很类似。

关键方法 

// 关联策略

enum {

    OBJC_ASSOCIATION_ASSIGN = 0, // 赋值

    OBJC_ASSOCIATION_RETAIN_NONATOMIC = 1, // 保留引用非原子对象 OBJC_ASSOCIATION_COPY_NONATOMIC = 3, // 复制非原子对象

    OBJC_ASSOCIATION_RETAIN = 01401, // 保留引用

    OBJC_ASSOCIATION_COPY = 01403 // 复制

};

objc_setAssociatedObject(id object,// 源对象

                         const void *key,// 关键字,key,根据这个key获取关联的对象

                         id value,// 要关联的对象,关联后这个对象的生命周期和源对象有关

                         objc_AssociationPolicy policy); // 关联策略

id objc_getAssociatedObject(id object, // 源对象

                            const void *key) // 关联对象使用的key,返回值是关联对象

实现

// 执行唯一关键字,用于获取关联对象

static void* PersonName = &PersonName;

static void* Dog = &Dog;

- (void)viewDidLoad {

    [superviewDidLoad];

    // 关联的使用,在不修改类的基础上给类增加新的属性

    // 比如说给对象SLQPerson增加一个姓名,关联一个dog对象

    NSString *name =  @"小明";

    SLQPerson *person1 = [[SLQPerson alloc] init];

    SLQDog *dog = [[SLQDog alloc] init];

    dog.dogName = @"旺财";

    

    // 关联对象

    objc_setAssociatedObject(person1, PersonName, name, OBJC_ASSOCIATION_RETAIN_NONATOMIC);

    objc_setAssociatedObject(person1, Dog, dog, OBJC_ASSOCIATION_RETAIN_NONATOMIC);

    NSString *person1Name = objc_getAssociatedObject(person1, PersonName);

    

    NSLog(@"%@------%@的小狗叫%@",person1,person1Name,dog.dogName);

    // 断开关联

    objc_setAssociatedObject(person1, PersonName, nil, OBJC_ASSOCIATION_RETAIN_NONATOMIC);

    objc_setAssociatedObject(person1, Dog, nil, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 

}

获取运行时的某个类的属性列表

首先包含头文件,然后使用里面的方法即可

// 运行时对象

#import <objc/runtime.h>

    // 遍历某个类里面所有属性 Ivar:表示成员属性

    // copyIvarList只能获取哪个类下面的属性,并不会越界(不会把它的父类的属性给遍历出来)

    // Class 获取哪个类的成员属性

    // count:告诉你当前类里面成员属性的总数

    //    unsigned int count = 0;

    //    // 返回成员属性的数组

    //

    int count = 0;

    Ivar *name =   class_copyIvarList([UIGestureRecognizer class], &count);

    for (int i = 0; i < count; i ++) {

        Ivar ivar = name[i];

        // 获取属性名

        NSString *proName = @(ivar_getName(ivar));

         NSLog(@"%@",proName);

    }

//<UIScreenEdgePanGestureRecognizer: 0x7fb6ba46f1c0; state = Possible; delaysTouchesBegan = YES; view = <UILayoutContainerView 0x7fb6ba7481b0>; target= <(action=handleNavigationTransition:, target=<_UINavigationInteractiveTransition 0x7fb6ba46d8e0>)>>

//UIScreenEdgePanGestureRecognizer:手势类型

//target - _UINavigationInteractiveTransition

//action - handleNavigationTransition

原文地址:https://www.cnblogs.com/songliquan/p/4634771.html