关联对象的如何进行内存管理的?关联对象如何实现weak属性

 

关联对象的存储结构

 

void _object_set_associative_reference(id object, void *key, id value, uintptr_t policy) {}

 

 

 

看到这里能够总结一下关联关系的存储结构了。

AssociationsHashMap是管理目标对象(object)与ObjectAssociationMap的关系

ObjectAssociationMap是管理Key与ObjectAssociation(关联对象)的关系。

 

 

 

1, 关联对象的ObjectAssociation中有两个属性(uintptr_t _policy, id value),
_policy 包含 retain, assgin copy, 会对应的对对象进行和普通对象一样的内存管理操作.

2 ,实现weak,用__weak修饰对象,并将其用block包裹,关联时,关联block对象

复制代码
-(void)setWeakvalue:(NSObject *)weakvalue {
    __weak typeof(weakvalue) weakObj = weakvalue;
    typeof(weakvalue) (^block)() = ^(){
        return weakObj;
    };
    objc_setAssociatedObject(self, weakValueKey, block, OBJC_ASSOCIATION_COPY_NONATOMIC);
}
-(NSObject *)weakvalue {
    id (^block)() = objc_getAssociatedObject(self, weakValueKey);
    return block();
}
复制代码

 

 

3.额外创造一个类WeakObjectContainer,在这个类里实现weak属性 weakObject ,虽然 分类里 retain 了一个 WeakObjectContainer,但是 WeakObjectContainer 最终会随着属性的持有对象一起销毁,不存在泄露。

WeakObjectContainer.h

@property (nonatomic, readonly, weak) id weakObject;
- (instancetype)initWithWeakObject:(id)object;

WeakObjectContainer.m

- (instancetype)initWithWeakObject:(id)object {
    self = [super init];
    if (self) {
        _weakObject = object;
    }
    
    return self;
}

 

NSObject+AssociateWeak.h

@property(weak, nonatomic) NSObject *weakObject;

 

NSObject+AssociateWeak.m

首先导入头文件

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

 

复制代码
NSString const *kKeyWeakObject = @"kKeyWeakObject";
-(void)setWeakObject:(NSObject *)weakObject
{
    WeakObjectContainer *container = [[WeakObjectContainer alloc] initWithWeakObject:weakObject];
    objc_setAssociatedObject(self, &kKeyWeakObject, (id)container, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
-(NSObject *)weakObject
{
    WeakObjectContainer *container = objc_getAssociatedObject(self, &kKeyWeakObject);
    return container.weakObject;
}
复制代码

 

posted @   黄增松  阅读(1360)  评论(0编辑  收藏  举报
编辑推荐:
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
阅读排行:
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
点击右上角即可分享
微信分享提示