iOS 开发 Objective-C 分类

iOS 底层 day07 Category上的关联对象

2020-08-29  本文已影响0人  望穿秋水小作坊

一、本文解答的问题

1. 为什么中添加属性可以赋值取值,而分类中添加的属性却不能直接赋值取值呢?
2. 不使用Objective-C提供的objc_setAssociatedObject 相关 API 我们能自己实现关联对象的效果吗?如果有,有哪些思路?
3. 观察下面代码,实现了关联对象效果,能否正常使用?有哪些缺点?可以优化吗?
// Person+Test1.h 
#import "Person.h"
@interface Person (Test1)
@property(nonatomic, assign) int age;
@end

// Person+Test1.m
#import "Person+Test1.h"
static int age_;

@implementation Person (Test1)
- (void)setAge:(int)age {
    age_ = age;
}
- (int)age {
    return age_;
}
@end
4. 我们对上面的代码优化一下,观察下面代码,实现了关联对象效果,能否正常使用?有哪些缺点?可以优化吗?
#import "Person+Test1.h"
#define SPKey [NSString stringWithFormat:@"%p",self]
static NSMutableDictionary *ageDic;
@implementation Person (Test1)
+ (void)load {
    ageDic = [[NSMutableDictionary alloc] init];
    
}
- (void)setAge:(int)age {
    [ageDic setObject:@(age) forKey:SPKey];
}
- (int)age {
    return [[ageDic valueForKey:SPKey] intValue];
}
@end
5. 用Objective-C提供的objc_setAssociatedObject 相关 API ,实现关联对象怎么做?
#import "Person+Test1.h"
#import <objc/runtime.h>
@implementation Person (Test1)
- (void)setAge:(int)age {
    objc_setAssociatedObject(self, @selector(age), @(age), OBJC_ASSOCIATION_ASSIGN);
}
- (int)age {
    return [objc_getAssociatedObject(self, @selector(age)) intValue];
}
@end
6. 关联对象的实现原理图解
关联对象的实现原理图解

二、关联对象源码解读

1. 掌握四个核心类
2. 核心源码
class AssociationsManager {
    static AssociationsHashMap *_map;
}

class AssociationsHashMap : public unordered_map<disguised_ptr_t, ObjectAssociationMap *>

class ObjectAssociationMap : public std::map<void *, ObjcAssociation>

class ObjcAssociation {
        uintptr_t _policy;
        id _value;
}

上一篇下一篇

猜你喜欢

热点阅读