for循环删除数组中的元素crash问题
如以下代码:
NSMutableArray *array = [NSMutableArray arrayWithObjects:@"2",@"3",@"4",@"9",@"4",@"12",@"22",@"4",@"4",@"5",@"6",@"1", nil];
for (NSString *str in array) {
if ([str isEqualToString:@"4"]) {
[array removeObject:str];
}
}
运行后肯定会crash,原因是数组越界。这是为什么?当我们正序快速遍历时,如果删除了一个,那么没有遍历到的元素位置都会往前移动一位,这样系统就无法确定接下来遍历是从删除位置开始呢,还是从删除位置下一位开始呢?这样就造成程序crash了。但是我们想要遍历删除时要怎么做?解决这个问题的方法有好几种。
出现这个崩溃的事件只会出现在快速遍历中。如果像以下代码不采用快速遍历,而是使用for循环,就不会出现问题。
for (int i = 0; i < array.count; i++) {
NSString *str = array[i];
if ([str isEqualToString:@"4"]) {
[array removeObject:str];
}
}
这两种有什么区别呢?
这是Apple官方文档中关于快速遍历的利弊。其中的note中显示,建议最好不要再快速遍历的时候修改enumerator,否则不保证是安全的.由此就明白了,可能是我们在快速遍历的时候,移除掉一个元素,但是计数器依旧是原来的,那么在遍历到最后会继续调用nextObject方法,而此时实际上已经全部遍历完了,但是系统并不知道,还在遍历,也就是越界;当发现没有元素时,就crash了;而我写的常规遍历法为什么就可以呢,那是因为i < self.btnArray.count,这个判断条件中,当数组元素个数变化时,self.btnArray.count也在变,就不会出现数组越界的情况,因此第二种方法是可行的;
第二种解决方法是定义一个副数组,遍历副本中的元素,在原数组中删除。
NSMutableArray *copyArray = [NSMutableArray arrayWithArray:array];
for (NSString *str in copyArray) {
if ([str isEqualToString:@"4"]) {
[array removeObject:str];
}
}
第三种方法是对数组逆序遍历,查找对应元素后删除
NSEnumerator *enumerator = [array reverseObjectEnumerator];
for (NSString *str in enumerator) {
if ([str isEqualToString:@"4"]) {
[array removeObject:str];
}
}
对于逆序遍历,因为我们逆序遍历时,遇到匹配的元素删除后,位置改变的是遍历过得元素,而没有遍历到的元素位置却没有改变,所以遍历能够正常进行.就不会crash。
解决方法列了这么几种,本人能力有限,如果有更好建议或者有什么不足,请联系我。
for循环删除数组中的元素crash问题的更多相关文章
- JS实现循环删除数组中元素的方法介绍
这篇文章主要给大家介绍了关于Javascript循环删除数组中元素的几种方法,文中给出了详细的示例代码供大家参考学习,对大家具有一定的参考学习价值,需要的朋友们下面来一起看看吧. 本文主要跟大家分享了 ...
- js 删除 数组中某个元素(转载)
来源:https://www.jb51.net/article/134312.htm js删除数组中某一项或几项的几种方法 https://www.jb51.net/article/154737.ht ...
- Javascript循环删除数组中元素的几种方法示例
发现问题 大家在码代码的过程中,经常会遇到在循环中移除指定元素的需求.按照常规的思路,直接一个for循环,然后在循环里面来个if判断,在判断中删除掉指定元素即可.但是实际情况往往不会像预想的那样顺利运 ...
- js删除数组中的元素delete和splice的区别
例如有一个数组是 :var textArr = ['a','b','c','d']; 这时我想删除这个数组中的b元素: 方法一:delete 删除数组 delete textArr[1] 结果为: ...
- Python笔记:用for循环删除列表中的元素
for运行过程中会有一个指针来记录当前循环的元素是哪一个,一开始这个指针指向第0个元素,然后获取它,接着删除第0个元素,这时候,原来是第1个的元素会变成第0个,当指针向后移动一次,指向了现在第1个元素 ...
- Java如何删除数组中的元素?
Java中,如何删除数组元素? 示例 以下示例显示如何从数组中删除元素. package com.yiibai; import java.util.ArrayList; public class Re ...
- python循环删除list中的元素
直接上例子: a = [1,2,3,4,5,6] for i in a: a.remove(i) print(a) 返回:[2, 4, 6] 循环a,想删除a的所有元素,但实际确有数据保留了下来,这是 ...
- jquery删除数组中重复元素
首先定义如下数组: var arr=[0,2,3,5,6,9,2]; 我们可以看到数组中存在重复元素'2'; 最后通过jquery筛选应该得到[0,2,3,5,6,9]; ok,首先我们再定义一个空数 ...
- [Perl] 删除数组中重复元素
写一个小程序时候,需要去除一个数组中的重复元素,搜索了一下,找到的代码主要是两种,一种是使用grep函数,一种是转换为hash表,代码分别如下: 使用grep函数代码片段:代码: my @array ...
- JS中删除数组中的元素方法
删除指定下标数组元素 Array.prototype.del=function(index){ if(isNaN(index)||index>=this.length){ return fals ...
随机推荐
- 如何在FastAPI中玩转WebSocket消息处理?
扫描二维码 关注或者微信搜一搜:编程智域 前端至全栈交流与成长 发现1000+提升效率与开发的AI工具和实用程序:https://tools.cmdragon.cn/ 一.文本消息接收与发送 # 运行 ...
- C#中数组(byte[])复制 拷贝
https://blog.csdn.net/alisa525/article/details/12518927 1,Array.Copy在CLR处理机制中最灵活,最强大,可装箱,拆箱复制,可加宽CLR ...
- Oracle并发控制
并发与锁定 当多用户同一时刻访问相同的数据库资源时,将产生并发.并发极易破坏数据的一致性.锁定是处理并发的重要手段,用户在修改某一资源前,必须首先获得资源的修改权.而这种修改权具有排他性. 并发与锁定 ...
- Flink初体验-批处理与流处理
一.环境准备 本机环境:jdk11.scala2.12.maven3.6 新建一个maven项目,pom如下 <?xml version="1.0" encoding=&qu ...
- JF 笔试 反思
ifconfig 是 window ipconfig 是 linux下的 搞混了 还有子网的信息,不清楚 有空看吧 所谓的Virtual Judge是区别于Online Judge而言的,OJ ...
- c++ stl iterator erase
简介 就是C++ 标准库程序删除元素. 其实很简单,只是做个记录 it = monkeys.erase(it); //删除元素后,迭代器失效, //要重新让迭代器指向被删元素的后面
- iPaaS丨企业应用及数据集成的重要性和挑战
在激烈的市场竞争中,企业服务总线和数据总线扮演着企业神经网络的角色,它们将不同的业务部门.系统以及数据紧密相连,保障信息流通无阻,实现资源的高效分配.这样的集成不仅提高了企业的运营效率,还增强了企业的 ...
- Streamlit入门 中文文档
基础概念 使用 Streamlit 进行开发非常简单.首先,在普通的 Python 脚本中添加几条 Streamlit 命令,然后使用 streamlit run 命令来运行它: streamlit ...
- Linux 系统启动过程-九五小庞
linux启动时我们会看到许多启动信息. Linux系统的启动过程并不是大家想象中的那么复杂,其过程可以分为5个阶段: 内核的引导. 运行 init. 系统初始化. 建立终端 . 用户登录系统. in ...
- 进阶篇:2.3)DFMA的运用方法(个人方法)
本章目的:将DFMA运用到实际中,个人方法谈. 1.DFMA事后补缺的运用步骤(实践) 1)准备DFMA设计检查表格(如果你所在公司用的是DFMA专用软件,请忽略): 2)准备设计原则对应的资料书籍: ...