iOS弱引用

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

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

解决方案一:

重写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方法SELSEL 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.rhkb.cn/news/394589.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数据库规范化设计 5大基本原则

规范化设计原则是数据库设计的基本原则,有助于减少数据冗余,提高数据一致性和完整性,简化数据管理,增强数据安全性,对整个开发项目至关重要。而缺乏规范化设计会导致数据冗余,增加存储成本,引发…

java 如何查看jar版本冲突,如何查看哪个模块依赖冲突,idea查看jar包冲突

1. idea 下载插件: 2. 如上图所示,下载Maven Helper, 注意是maven helper 不是别的 3.重启idea 4.点击pom文件,然后点击如图所示: 5. 如此即可查到,某个jar包 都有哪个模块依赖,使用的什么版本&#xff0…

【JavaEE】定时器

目录 前言 什么是定时器 如何使用java中的定时器 实现计时器 实现MyTimeTask类 Time类中存储任务的数据结构 实现Timer中的schedule方法 实现MyTimer中的构造方法 处理构造方法中出现的线程安全问题 完整代码 考虑在限时等待wait中能否用sleep替换 能否用PriorityBlo…

RISC-V竞赛|第二届 RISC-V 软件移植及优化锦标赛报名正式开始!

目录 赛事背景 赛道方向 适配夺旗赛 优化竞速赛 比赛赛题(总奖金池8万元!) 🔥竞速赛 - OceanBase 移植与优化 比赛赛程(暂定) 赛事说明 「赛事背景」 为了推动 RISC-V 软件生态更快地发展&#xff0…

收银系统源码-连锁店版本

千呼新零售2.0系统是零售行业连锁店一体化收银系统,包括线下收银线上商城连锁店管理ERP管理商品管理供应商管理会员营销等功能为一体,线上线下数据全部打通。 私有化独立部署/全开源源码,系统开发语言: 核心开发语言: PHP、HTML…

【vue3】【elementPlus】【黑暗模式】

从创建vue3项目到引入elementPlus组件并设置黑暗模式 1.创建vue3项目: npm init vuelatest1.1 根据需求定制项目插件: 2.引入elementPlus组件: npm install element-plus --save2.1 如图注册全局elementPlus组件: ------------…

SPSS、Python员工满意度问卷调查激励保健理论研究:决策树、随机森林和AdaBoost|附代码数据

全文链接:https://tecdat.cn/?p37293 原文出处:拓端数据部落公众号 在深入了解公司当前的实际情况和员工内心真实想法的基础上,我们旨在从专业视角出发,为企业在组织管理方面的不足进行诊断,并进行全面审视。 为了…

vue实现PC端图片放大缩小可鼠标拖动,鼠标滚轮控制放大缩小完整代码付效果图

vue实现图片放大缩小可鼠标拖动&#xff0c;鼠标滚轮控制放大缩小完整代码付效果图 效果图&#xff1a; 创建一个ImageViewer 组件&#xff0c;并且在当前页面引用完整代码如下&#xff1a; 代码引用&#xff1a; <template><view><image-viewer :imageUrl&q…

2024年必备技能:智联招聘岗位信息采集技巧全解析

随着大数据时代的发展&#xff0c;精准定位职业机会成为程序员求职的关键。本文将深入解析如何利用Python高效采集智联招聘上的岗位信息&#xff0c;助你在2024年的职场竞争中脱颖而出。通过实战代码示例&#xff0c;揭示网络爬虫背后的秘密&#xff0c;让你轻松掌握这一必备技…

苹果应用程序清理卸载工具:App Cleaner Uninstaller Pro for Mac

App Cleaner & Uninstaller Pro 是一款专为 Mac OS X 操作系统设计的应用程序清理和卸载工具。这款软件的主要功能是帮助用户彻底删除不需要的应用程序、插件和残留文件&#xff0c;从而释放磁盘空间并提高系统性能。 特点和优势&#xff1a; 彻底卸载应用程序&#xff1a;…

历代文学-技术生态-总体介绍

1. 历代文学简介 历代文学&#xff08;https://literature.sinhy.com/#/literature?__c1000&#xff0c;微信小程序可直接搜索“历代文学”&#xff09;是一个由两个人&#xff08;一个后端和一个前端&#xff09;开发的文学网站&#xff0c;是一个收录从古到今、以及古今中外…

几款设计师必备的AI抠图软件工具分享给你!

前言 在图像处理领域&#xff0c;抠图是一项基本而关键的技能。传统上&#xff0c;PS是作为抠图的首选工具&#xff0c;但其操作复杂性往往令初学者望而却步。幸运的是&#xff0c;随着AIGC技术的发展&#xff0c;现在有多款AI软件和在线网站能够以更简单、快捷的方式完成抠图…

VS+Qt+C++点云PCL三维显示编辑系统

程序示例精选 VSQtC点云PCL三维显示编辑系统 如需安装运行环境或远程调试&#xff0c;见文章底部个人QQ名片&#xff0c;由专业技术人员远程协助&#xff01; 前言 这篇博客针对《VSQtC点云PCL三维显示编辑系统》编写代码&#xff0c;代码整洁&#xff0c;规则&#xff0c;易…

【wiki知识库】08.添加用户登录功能--后端SpringBoot部分

目录 一、今日目标 二、SpringBoot后端实现 2.1 新增UserLoginParam 2.2 修改UserController 2.3 UserServiceImpl代码 2.4 创建用户上下文工具类 2.5 通过token校验用户&#xff08;重要&#xff09; 2.6 创建WebMvcConfig 2.7 用户权限校验拦截器 一、今日目标 上篇…

【大模型】大模型指令微调的“Prompt”模板

文章目录 一、微调数据集格式二、常用的指令监督微调模板2.1 指令跟随格式&#xff08;Alpaca&#xff09;2.2 多轮对话格式&#xff08;ShareGPT&#xff09;2.3 其他形式2.4 常见模板 参考资料 一、微调数据集格式 在进行大模型微调的过程中&#xff0c;我们会发现“Prompt”…

mysql 日志爆满,删除日志文件,定时清理日志

今天发现网站不能正常访问&#xff0c;于是登陆服务器查找问题。 机智的我随手用命令&#xff1a;df -l 发现 硬盘爆满了&#xff0c;于是就知道问题所在了。 Filesystem 1K-blocks Used Available Use% Mounted on/dev/xvda1 20641404 16963004 16929876 10…

安捷伦N9918A是德keysight N9918B 30khz-26.5g频谱分析仪

Agilent N9918A、Keysight N9918B、 FieldFox 手持式射频和微波组合分析仪&#xff0c;30 kHz - 26.5 GHz 附加功能&#xff1a; 30 kHz 至 26.5 GHz动态范围&#xff1a;100 dBCAT&#xff1a;故障点距离、回波损耗、电缆损耗VNA&#xff1a;S11、S21、S22、S12、幅度和相位…

PMP考试一定要考到3A吗?怎么备考?

PMP&#xff08;Project Management Professional&#xff09;认证是全球公认的项目管理专业人士资格认证&#xff0c;它代表着项目管理领域的高水平标准。 在备考PMP考试时&#xff0c;有些赛宝关心是否需要考到3A&#xff08;即三个领域均为Above Target&#xff0c;超出目标…

GoFly快速开发框架代码市场使用说明

说明 我们框架坚持开源的项目绝不能存在收费项目&#xff0c;所以我们gofly快速开发开源版没有内置代码仓插件&#xff0c;因此需要使用代码市场中的代码包需要再企业版中使用&#xff0c;代码市场插件如下&#xff1a; 图1、社区-代码市场​​​​ 他和企业版管理后台的代码仓…

慢SQL优化的30个思路方案整理

文章目录 &#xff08;1&#xff09;索引优化&#xff08;2&#xff09;查询重构&#xff08;3&#xff09;减少数据扫描量&#xff08;4&#xff09;利用缓存&#xff08;5&#xff09;分区表&#xff08;6&#xff09;优化排序和分组&#xff08;7&#xff09;业务查询条件限…