iOS弱引用

news2024/9/23 17:22:20

背景:在面试过程中被问到如果两个对象已经发生循环引用了,该如何将他们剪断,在运行态的时候。

由于这个场景比较抽象,我理解面试官是希望我通过运行时的方法和方式来解决循环引用。

解决方案一:

重写setter用关联对象来实现weak引用。由于objc_setAssociatedObject中的策略不支持weak修饰对象属性。如果我们可以借助中间类或者block持有弱引用对象来实现。

- (void)setMyObject:(id)myObject
{
    id __weak weakObject = myObject;
    id (^block)(void) = ^ {
        return weakObject;
    };
    objc_setAssociatedObject(self, @selector(myObject), block, OBJC_ASSOCIATION_COPY_NONATOMIC);
}

- (id)myObject
{
    id (^block)(void) = objc_getAssociatedObject(self, _cmd);
    return block();
}

解决方案二:

还是重写setter通过关联对象实现弱引用,但是弱引用的实现不是通过中间对象的方式,而是通过runtime运行时重写value对象的子类的delloc方法,在这个方法中将关联对象的value设置成ni;

void weak_setAssociatedObject(id _Nonnull object,
                              const void * _Nonnull key,
                              id _Nullable value) {
    //派生一个子类,类名为WeakObjWrapper+value对应的类名
    const char *clsName = [[NSString stringWithFormat:@"WeakObjWrapper%@", [value class]] UTF8String];
    
    //获取派生的子类
    Class childCls = objc_getClass(clsName);
    
    //如果子类不存在,利用runtime动态的创建一个子类
    if (!childCls) {
        childCls = objc_allocateClassPair([value class], clsName, 0);
        objc_registerClassPair(childCls);
    }
    //注册dealloc方法SEL
    SEL sel = sel_registerName("dealloc");
    
    //获取dealloc对应的类型编码
    const char *deallocEncoding = method_getTypeEncoding(class_getInstanceMethod([value class], sel));
    
    // 注意:内部持有value此处需要弱引用处理一下
    __weak typeof(value) weakValue = value;
    
    // 创建一个指向在调用dealloc方法时调用指定block的函数指针
    IMP deallocImp = imp_implementationWithBlock(^(id _childCls) {
        //在子类的dealloc方法中将value设置为nil,避免崩溃
        objc_setAssociatedObject(object, key, nil, OBJC_ASSOCIATION_ASSIGN);
        //派生的子类的dealloc方法会被调用,父类的不再被调用,故在此处调用一下父类的
        ((void (*)(id, SEL))(void *)objc_msgSend)(weakValue, sel);
    });
    
    //给子类添加dealloc方法
    class_addMethod(childCls, sel, deallocImp, deallocEncoding);
    
    //将value对应的isa指向子类
    object_setClass(value, childCls);
    
    //设置关联对象
    objc_setAssociatedObject(object, key, value, OBJC_ASSOCIATION_ASSIGN);
}

- (id)anthorObj
{
    return objc_getAssociatedObject(self, _cmd);
}

- (void)setAnthorObj:(id)anthorObj
{
    weak_setAssociatedObject(self, @selector(anthorObj), anthorObj);
}

测试代码如下:

Engine * a = [[Engine alloc] init];
    {
        Tire * b = [[Tire alloc] init];
        Tire * c = [[Tire alloc] init];
        a.myObject = b;
        a.anthorObj = c;
        NSLog(@"myObject%@", a.myObject);
        NSLog(@"anthorObject%@", a.anthorObj);
    }
    NSLog(@"myObject outer%@", a.myObject);
    NSLog(@"anthorObject outer%@", a.anthorObj);

可以看到过了b、c对象出了作用域后,a.myObject以及a.anthorObject被改成nil.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1971883.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【C++11】:右值引用移动语义完美转发

目录 前言一,左值引用和右值引用二,左值引用与右值引用比较三,探索引用的底层四,右值引用使用场景和意义4.1 解决返回值问题4.2 STL容器插入接口的改变 五,移动语义六,完美转发6.1 模板中的&& 万能…

【动态路由协议】RIP

一、前导知识 动态路由协议分类: 1.IGP(内部网关协议,位于同一个自治系统内) 1.1距离矢量路由协议 RIP(距离矢量路由) 1.2链路状态路由协议 OSPF(开放式最短路径优先) IS-IS(中间系统到中间系统…

Xinstall新玩法:Web直接打开App,用户体验再升级!

在移动互联网时代,App已成为我们日常生活中不可或缺的一部分。然而,在App推广和运营过程中,许多开发者面临着从Web端引流到App的难题。这时,Xinstall作为国内专业的App全渠道统计服务商,提供了一种创新的解决方案——通…

【前端 21】Vue Router路由配置

Vue Router路由配置 在Vue.js项目中,Vue Router是官方提供的路由管理器,用于构建单页面应用(SPA)。它允许我们通过不同的URL访问不同的页面组件,而无需重新加载页面。下面,我将详细介绍如何在Vue项目中配置…

【研发日记】Matlab/Simulink技能解锁(十二)——Stateflow中的两种状态机嵌套对比

文章目录 前言 项目背景 两级状态机 函数状态机 分析和应用 总结 参考资料 前言 见《【研发日记】Matlab/Simulink技能解锁(七)——两种复数移相算法》 见《【研发日记】Matlab/Simulink技能解锁(八)——分布式仿真》 见《【研发日记】Matlab/Simulink技能解锁(九)——基…

将 HuggingFace 模型转换为 GGUF 及使用 ollama 运行 —— 以 Qwen2-0.5B 为例

前言 最近,阿里发布了Qwen2的系列模型,包括0.5B, 1.5B, 7B, 57B-A14B 和 72B,中英文效果都很好。 因为模型太新,目前还没有 GGUF 版本可以下载,于是转下GGUF,并分享转换教程。 什么是 GGUF? …

[VS Code扩展]写一个代码片段管理插件(一):介绍与界面搭建

文章目录 VS Code扩展机制项目搭建创建UI元素活动栏按钮主边栏视图主边栏工具栏按钮侧边栏右键菜单编辑器右键菜单 项目地址 [VS Code扩展]写一个代码片段管理插件(一):介绍与界面搭建[VS Code扩展]写一个代码片段管理插件(二&…

Io.net系统概述-核心功能;Io,net自动匹配资源与任务;两种令牌:IO和IOSD;

目录 Io.net 一、系统概述 二、核心功能 三、经济系统 四、产品与服务 五、团队与融资 六、市场前景与竞争优势 Io,net自动匹配资源与任务 一、动态资源分配机制 二、高级算法自动匹配资源与任务 三、用户界面与反馈机制 两种令牌:IO和IOSD。简单举例说明 $IO令牌…

2024四大硬盘数据恢复工具推荐!

不知道你有没有遇到过这种情况,电脑里的重要文件突然就不见了,可能是不小心删了,或者是硬盘出了点小问题。这时候,下面这几个好用的硬盘数据恢复工具就能帮你解决问题! 一、福昕数据恢复 链接:www.pdf365…

【从英文中重建数字】python刷题记录

R2-字符串 目录 解简单方程法 线性代数法 ps: 就是从里面找出one,two,zero,---nine 想到哈希表,key代表单词,value代表0---9 用t表示单词,那不就是t在s中的查找问题了吗 但这样显然有些麻烦,在于t是不确定的,t需要遍历一遍keys()&…

万物分割(Segment Anything Model)C++模型推理部署

概述 SAM 是一种先进的人工智能模型,已经证明了在分割复杂和多样化图像方面具有优异的表现。该模型是计算机视觉和图像分割领域的一个重大突破。 SAM 的架构旨在处理各种图像分割任务,包括对象检测、实例分割和全景分割。这意味着该模型可以应用于各种用…

2024年Google Play上架指南:开发者账号与上包环境防关联

移动应用市场瞬息万变,成功上架Google Play商店无疑是每一位开发者的重要目标。然而,要确保应用程序顺利通过审核并获得持久的上架资格,开发者需要格外重视账号注册和上包环境管理这两个关键环节。 近年来,Google不断加强对开发者…

vtk2three之用three绘制vtk的Calculator公式

Calculator公式 vtk里面可以用这个过滤器filter,来绘制一个公式的点阵,想着其实可以把这个作为第一个切入点来把vtk里面的数据源引入到threejs里面,把threejs当作一个render,dataSource就是来自于这个vtk,下面先上一个…

字符串的模拟算法(思路+例题)

👏大家好!我是和风coding,希望我的文章能给你带来帮助! 🔥如果感觉博主的文章还不错的话,请👍三连支持👍一下博主哦 📝点击 我的主页 还可以看到和风的其他内容噢&#x…

华为的流程体系

缘由 2010年,华为销售额为1850亿元,其中国际市场占65%,净利润238亿元。当时,公司员工达11万人,公司处理合同达5万多个,290万个订单,大量的工作是手工处理,没有统一的流程支持&#…

《技术人求职之道》之面试准备篇:不打无准备之仗,优秀技术人的面试前准备

摘要 本文为求职者提供面试前的全面准备策略,旨在提升面试成功几率并减轻面试前的焦虑和不自信。文章首先强调准备求职资料的重要性,包括简历、寸照、学历证明等,并建议提前准备以避免入职时的尴尬。接着,讨论对应聘公司进行调研的必要性,包括了解公司业务和技术需求,以…

MySQL基础练习题19-查找拥有有效邮箱的用户

题目:查找具有有效电子邮件的用户 准备数据 分析数据 总结 题目:查找具有有效电子邮件的用户 一个有效的电子邮件具有前缀名称和域,其中: 前缀 名称是一个字符串,可以包含字母(大写或小写)&…

修改mac的音量能像windows系统那样给出音量反馈吗?

一、背景 windows有一些非常好的设计,比如拖动音量条的时候会有对应的音量大小的反馈。有时还能用来确定是视频没声音还是电脑坏了 在mac里怎么设置? 二、方法 首先点击菜单栏音量按钮->声音偏好设置…->勾选 “当更改音量时播放反馈”。 mac…

论文阅读:Mammoth: Building math generalist models through hybrid instruction tuning

Mammoth: Building math generalist models through hybrid instruction tuning https://arxiv.org/pdf/2309.05653 MAmmoTH:通过混合指令调优构建数学通才模型 摘要 我们介绍了MAmmoTH,一系列特别为通用数学问题解决而设计的开源大型语言模型&#…

书生大模型训练营 - 练习一

最近想了解一下大模型,查看了《2024大模型典型示范应用》文档,发现有公司使用的是书生大模型,正好发现他们有训练营,此文章记录的大模型作业。 一、各种链接 书生大模型官网:https://internlm.intern-ai.org.cn/ 进训…