Objective-C使用块枚举的细节

对元素类型的要求

在 Objective-C 中,NSArray 只能存储对象类型,而不能直接存储基本类型(例如 int)。但是,可以将基本类型封装在 NSNumber 等对象中,然后将这些对象存储在 NSArray 中。这样,enumerateObjectsUsingBlock: 方法中的 obj 仍然是指向这些对象的指针。

NSArray *array = @[@1, @2, @3];
[array enumerateObjectsUsingBlock:^(NSNumber *obj, NSUInteger idx, BOOL *stop) {int value = [obj intValue];NSLog(@"Object: %@, Int Value: %d, Address: %p", obj, value, obj);
}];

obj 是一个指针变量,局部变量

obj 和 array 中对应位置的元素指向相同的内存地址,但它们不是同一个指针变量,而是两个指向同一对象的不同变量。

在 -enumerateObjectsUsingBlock: 方法中,块枚举会遍历数组,并将每个元素的指针赋值给 obj。因此,obj 是一个局部变量,在每次迭代时指向数组中当前遍历的元素。尽管它们指向同一对象,但 obj 是块中的局部变量,而数组中的元素是数组中的存储单元。

NSArray *array = @[@"one", @"two", @"three"];
[array enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {NSLog(@"Object: %@, obj Address: %p, obj Pointer Address: %p, array[idx] Address: %p, array[idx] pointer Address: %p", obj, obj, &obj, array[idx], &array[idx]);
}];

循环引用问题

在 Objective-C 中使用 enumerateObjectsUsingBlock 时,同样需要注意循环引用问题。enumerateObjectsUsingBlock 会将块传递给枚举方法,如果块捕获了对自身或外部对象的强引用,这可能导致循环引用,尤其是当这个对象也强引用调用该块的对象时。

示例说明

假设有一个类 MyClass,其实例方法使用 enumerateObjectsUsingBlock

@interface MyClass : NSObject
@property (nonatomic, strong) NSArray *array;
@end@implementation MyClass- (void)enumerateArray {[self.array enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {// 这里使用了 selfNSLog(@"%@", self);}];
}@end

在上述代码中,块捕获了 self 的强引用。如果 self 对象持有 array,这就形成了一个循环引用,导致 self 无法被释放。

解决方案

使用弱引用来打破循环引用,可以使用 __weak__block 关键字:

@implementation MyClass- (void)enumerateArray {__weak typeof(self) weakSelf = self;[self.array enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {// 这里使用了弱引用的 self__strong typeof(weakSelf) strongSelf = weakSelf;if (strongSelf) {NSLog(@"%@", strongSelf);}}];
}@end

在这个修改后的代码中,使用 __weakself 的弱引用传递到块内,然后在块内将其转换为强引用以确保在使用过程中对象的生命周期被正确管理。

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

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

相关文章

Maven编译打包时报“PKIX path building failed”异常

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 方法11.报错信息2.InstallCert.java3.生成证书文件 jssecacerts4.复制 jssecacerts 文件5. 然后重启Jenkins 或者maven即可 方法21.下载证书2. 导入证书执行keytool…

7.优化算法之分治-快排归并

0.分治 分而治之 1.颜色分类 75. 颜色分类 - 力扣(LeetCode) 给定一个包含红色、白色和蓝色、共 n 个元素的数组 nums ,原地对它们进行排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列。 我们使用整数…

Elasticsearch (1):ES基本概念和原理简单介绍

Elasticsearch(简称 ES)是一款基于 Apache Lucene 的分布式搜索和分析引擎。随着业务的发展,系统中的数据量不断增长,传统的关系型数据库在处理大量模糊查询时效率低下。因此,ES 作为一种高效、灵活和可扩展的全文检索…

PHP爬虫类的使用技巧与注意事项

php爬虫类的使用技巧与注意事项 随着互联网的迅猛发展,大量的数据被不断地生成和更新。为了方便获取和处理这些数据,爬虫技术应运而生。PHP作为一种广泛应用的编程语言,也有许多成熟且强大的爬虫类库可供使用。在本文中,我们将介…

Qt Creator 的设置文件保存位置

在使用 Qt Creator 进行开发时,备份或迁移设置(例如文本编辑器偏好、语法高亮等)是常见需求。了解这些设置文件在不同操作系统中的保存位置,可以简化这个过程。本文将为您详细介绍 Qt Creator 保存设置文件的位置。 默认文件位置 Qt Creator 会创建多个文件和目录来存储其…

springboot系列八: springboot静态资源访问,Rest风格请求处理, 接收参数相关注解

文章目录 WEB开发-静态资源访问官方文档基本介绍快速入门注意事项和细节 Rest风格请求处理基本介绍应用实例注意事项和细节思考题 接收参数相关注解基本介绍应用实例PathVariableRequestHeaderRequestParamCookieValueRequestBodyRequestAttributeSessionAttribute ⬅️ 上一篇…

微服务-网关Gateway

个人对于网关路由的理解: 网关就相当于是一个项目里面的保安,主要作用就是做一个限制项。(zuul和gateway两个不同的网关) 在路由中进行配置过滤器 过滤器工厂:对请求或响应进行加工 其中filters:过滤器配置…

探索QCS6490目标检测AI应用开发(三):模型推理

作为《探索QCS6490目标检测AI应用开发》文章,紧接上一期,我们介绍如何在应用程序中介绍如何使用解码后的视频帧结合Yolov8n模型推理。 高通 Qualcomm AI Engine Direct 是一套能够针对高通AI应用加速的软件SDK,更多的内容可以访问&#xff1a…

摸鱼大数据——Spark基础——Spark环境安装——PySpark搭建

三、PySpark环境安装 PySpark: 是Python的库, 由Spark官方提供. 专供Python语言使用. 类似Pandas一样,是一个库 Spark: 是一个独立的框架, 包含PySpark的全部功能, 除此之外, Spark框架还包含了对R语言\ Java语言\ Scala语言的支持. 功能更全. 可以认为是通用Spark。 功能 P…

Golang | Leetcode Golang题解之第199题二叉树的右视图

题目: 题解: /** 102. 二叉树的递归遍历*/ func levelOrder(root *TreeNode) [][]int {arr : [][]int{}depth : 0var order func(root *TreeNode, depth int)order func(root *TreeNode, depth int) {if root nil {return}if len(arr) depth {arr a…

线性代数--行列式1

本篇来自对线性代数第一篇的行列式的一个总结。 主要是行列式中有些关键点和注意事项,便于之后的考研复习使用。 首先,对于普通的二阶和三阶行列式,我们可以直接对其进行拆开,展开。 而对于n阶行列式 其行列式的值等于它的任意…

每个架构师都应该读的八本经典书籍

格雷戈尔霍普在本文讨论了8本被视为软件架构师必读的经典书籍。 以下是所提及的关键书籍的摘要: 1、维特鲁威(公元前 20 年)的《建筑学》: 虽然与软件架构没有直接关系,但这部古代文献被提及,具有历史背景…

C++特殊类设计单例模式...

文章目录 请设计一个类,不能被拷贝请设计一个类,只能在堆上创建对象请设计一个类,只能在栈上创建对象请设计一个类,不能被继承请设计一个类,只能创建一个对象(单例模式)单例模式:饿汉模式:懒汉模…

代发考生战报:6月25号 南宁 HCIP-Transmission传输 H31-341考试884分通过

代发考生战报:6月25号 南宁 HCIP-Transmission传输 H31-341考试884分通过 ,今天我和同事两个人去考的,我考试遇到1个新题,他遇到两个新题,客服提供的题库很稳定,全覆盖了,轻松通过,考…

【语言模型】Xinference的部署过程

一、引言 Xinference,也称为Xorbits Inference,是一个性能强大且功能全面的分布式推理框架,专为各种模型的推理而设计。无论是研究者、开发者还是数据科学家,都可以通过Xinference轻松部署自己的模型或内置的前沿开源模型。Xinfe…

pikachu靶场 利用Rce上传一句话木马案例(工具:中国蚁剑)

目录 一、准备靶场,进入RCE 二、测试写入文件 三、使用中国蚁剑 一、准备靶场,进入RCE 我这里用的是pikachu 打开pikachu靶场,选择 RCE > exec "ping" 测试是否存在 Rce 漏洞 因为我们猜测在这个 ping 功能是直接调用系统…

性能评测系列:云架构扩展演进横向对比

原始测评报告 性能评测系列(PT-010):Spring Boot RDS for MySQL,高并发insert 性能评测系列(PT-012):Spring Boot(K8s多实例) RDS for MySQL,高并发insert 性能评测系列&#xff…

一元线性回归-R语言

# # 安装包 # install.packages(ggplot2) # library(ggplot2) Sys.setlocale(category LC_ALL, locale English_United States.1252) # Sys.setlocale("LC_ALL","Chinese") x <- c(18, 20, 22, 24, 26, 28, 30) y <- c(26.86, 28.35, 28.87,28.75,…

Linux——vim的配置文件+异常处理

vim的配置文件&#xff1a; [rootserver ~]# vim /etc/vimrc # 输入以下内容 set nu # 永久设置行号 shell [rootserver ~]# vim /etc/vimrc 或者 vim ~/.vimrc set hlsearch "高亮度反白 set backspace2 "可随时用退格键删除 set autoindent…

期货的杠杆怎么计算?

什么是杠杆系数 杠杆系数是指期货合约价值与保证金之间的比例。它表示投资者只需投入少量资金&#xff0c;就可以控制价值更高的期货合约。杠杆系数越高&#xff0c;投资者的资金放大倍数就越大&#xff0c;但风险也越大。 什么是期货保证金呢&#xff1f; 期货保证金&…