美文网首页
关联对象学习

关联对象学习

作者: 朝夕向背 | 来源:发表于2018-11-11 20:19 被阅读0次

在没有介绍关联对象之前,先看一道面试题

Category能否添加成员变量?如果可以,如何给Category添加成员变量?

Cateogry底层学习笔记中,注意的第一条category里面不能添加成员变量。但是可以通过关联对象间接的实现成员变量效果

在Category中,给分类添加属性方法,只会给分类添加属性的set方法和get方法的声明。不会像在类中,给类添加属性,同时生成成员变量,set方法的声明和实现以及get方法的声明和实现。我们来看下Category的底层结构图:

Category的底层结构
在Category的底层结构中,包括实例方法列表method_list_t、类方法列表method_list_t、协议列表protocol_list_t、属性列表property_list_t。但是没有成员变量列表ivars
所以要实现成员变量功能,可以通过其他方式,关联对象就是其中的一种方式。
我们先看下,关联对象的使用方式
main.m的调用方式
#import <Foundation/Foundation.h>
#import "Person.h"
#import "Person+Test3.h"

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        Person *person = [[Person alloc] init];
        person.name = @"糖糖";
        NSLog(@"%d  %d %@",person.weight,person.height,person.name);
    }
    return 0;
}

类文件

#import <Foundation/Foundation.h>

@interface Person : NSObject

@end

#import "Person.h"

@implementation Person

@end

在分类中使用关联对象

#import "Person.h"

@interface Person (Test3)
@property (nonatomic, copy)  NSString *name;
@end

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

@implementation Person (Test3)

- (void)setName:(NSString *)name{
    objc_setAssociatedObject(self,@selector(name),name,OBJC_ASSOCIATION_COPY_NONATOMIC);
}

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

@end

关联对象的原理

实现关联对象技术的核心对象有
AssociationsManager
AssociationsHashMap
ObjectAssociationMap
ObjcAssociation

AssociationsManager内部有static AssociationsHashMap *_map;

void objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy) {
    _object_set_associative_reference(object, (void *)key, value, policy);
}

AssociationsHashMap的内部,包含ObjectAssociationMap

    class AssociationsHashMap : public unordered_map<disguised_ptr_t,
 ObjectAssociationMap *, DisguisedPointerHash, 
DisguisedPointerEqual, AssociationsHashMapAllocator> {
...
    };

ObjectAssociationMap内部包含ObjcAssociation

    class ObjectAssociationMap : public std::map<void *, ObjcAssociation, ObjectPointerLess, ObjectAssociationMapAllocator> {
...
    };

ObjcAssociation内部,有两个重要属性_policy,_value

 class ObjcAssociation {
        uintptr_t _policy;
        id _value;
...
    };

objc_setAssociatedObject(object, const void *key, id value, objc_AssociationPolicy policy)方法中,传入的参数valuepolicy,最后传入ObjcAssociation内部。

四个核心对象的关系图
  • AssociationsManager内部的AssociationsHashMap有成对的keydisguised_ptr_t和valueObjectAssociationMap值。
  • ObjectAssociationMap内部也有成对的key值void *和value值ObjectAssociation
  • ObjectAssociation内部有valuepolicy
    objc_setAssociatedObject(object, const void *key, id value, objc_AssociationPolicy policy)方法内,
  • object是key值disguised_ptr_t
  • const void *key是key值void *
  • id value 是ObjectAssociation内部的valuebjc_AssociationPolicy policy是ObjectAssociation内部的policy`。

相关文章

  • 关联对象学习

    在没有介绍关联对象之前,先看一道面试题 Category能否添加成员变量?如果可以,如何给Category添加成员...

  • Swift 为分类增加属性objc_getAssociated

    OC 获取关联对象 Swift 获取关联对象——错误的写法 Swift 获取关联对象——正确的写法 设置关联对象 ...

  • iOS runtime关联对象 objc_setAssociat

    关联对象的作用: 关联对象可以给某个对象关联一个或者多个其他对象,这些对象通过健来区分。 创建存储关联对象objc...

  • 关联对象

    关联对象的方式 关联对象源码基本思路 关联对象的结构:AssociationsHashManager // Ass...

  • RunTime学习笔记——关联对象

    现在你准备用一个系统的类,但是系统的类并不能满足你的需求,你需要额外添加一个属性。 这种情况的一般解决办法就是继承...

  • 关联对象

    关联对象原理 关联对象并不是存储在被关联对象本身内存中,关联对象存储在全局的统一的一个AssociationsMa...

  • objc_setAssociatedObject

    iOS objc_setAssociatedObject 关联对象的学习 今天看了FDTemplateLayout...

  • iOS 关联对象

    概述 关联对象顾名思义,就是给对象关联对象的意思,一个对象可以关联多个其他对象,这些对象通过key来区分,存储对象...

  • 关联对象

    关联对象会用被关联对象作为key,将关联对象存储到全局的哈希表里。 AssociationHashMap Asso...

  • iOS关联对象技术原理

    iOS关联对象技术原理 iOS关联对象技术原理

网友评论

      本文标题:关联对象学习

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