解决EXC_BAD_ACCESS

iOS内存错误EXC_BAD_ACCESS的解决方法 iOS开发,最郁闷的莫过于程序毫无征兆地就崩溃了,用bt命令打出调用栈,给出的是一堆系统EXC_BAD_ACCESS的信息,根本没办法定位问题出现在哪里 立即下载

现了一篇非常好的文章,立刻转过来。感谢原作者,帮我们解决了EXC_BAD_ACCESS这个棘手的问题。

本文转自:http://ibuick.com/buick2011820/index.php/archives/objective-c-exc_bad_access

-------------------------------------------

 

写程序遇到 Bug 并不可怕,大部分的问题,通过简单的 Log 或者 代码分析并不难找到原因所在。但是在 Objective-C 编程中遇到 EXC_BAD_ACCESS 问题的时候,通过简单常规的手段很难发现问题。这篇文章,给大家介绍一个常用的查找 EXC_BAD_ACCESS 问题根源的方法。

首先说一下 EXC_BAD_ACCESS 这个错误,可以这么说,90%的错误来源在于对一个已经释放的对象进行release操作。

举一个简单的例子来说明吧,首先看一段Java代码:

public class Test{
        public static void main(String[] args){
                String s = “This is a test string”;
                s = s.substring(s.indexOf(“a”),(s.length()));
                System.out.println(s);
                
        }
}

这种写法在Java中很常见也很普遍,这不会产生任何问题。但是到了 Objective-C 中,就会出事,考虑这个程序:

#import <Foundation/Foundation.h>

int main (int argc, const char * argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
        NSString* s = [[NSString alloc]initWithString:@”This is a test string”];
        s = [s substringFromIndex:[s rangeOfString:@"a"].location];//内存泄露
        [s release];//错误释放
[pool drain];//EXC_BAD_ACCESS
return 0;
}

这个例子当然狠容易的看出问题所在,如果这段代码包含在一个很大的逻辑中,确实容易被忽略。Objective-C 这段代码有三个致命问题,1,内存泄露。2,错误释放。3,造成 EXC_BAD_ACCESS 错误。

1, NSString* s = [[NSString alloc]initWithString:@”This is a test string”]; 创建了一个 NSString Object,随后的 s = [s substringFromIndex:[s rangeOfString:@"a"].location]; 执行后,导致创建的对象引用消失,直接造成内存泄露。

2,错误释放。[s release]; 这个问题,原因之一是一个逻辑错误,以为 s 还是我们最初创建的那个 NSString 对象。第二是因为从 substringFromIndex:(NSUInteger i) 这个方法返回的 NSString 对象,并不需要我们来释放,它其实是一个被 substringFromIndex 方法标记为 autorelease 的对象。如果我们强行的释放了它,那么会造成 EXC_BAD_ACCESS 问题。

3: EXC_BAD_ACCESS。由于 s 指向的 NSString 对象被标记为 autorelease, 则在 NSAutoreleasePool 中已有记录。但是由于我们在前面错误的释放了该对象,则当 [pool drain] 的时候,NSAutoreleasePool 又一次的对它记录的 s 对象调用了 release 方法,但这个时候 s 已经被释放不复存在,则直接导致了 EXC_BAD_ACCESS问题。

那么,知道了 EXC_BAD_ACCESS 的诱因之一后,如何快速高效的定位问题?

1: 为工程运行时加入 NSZombieEnabled 环境变量,并设为启用,则在 EXC_BAD_ACCESS 发生时,XCode 的 Console 会打印出问题描述。

首先双击 XCode 工程中,Executables 下的 可执行模组,

 

 

在弹出窗口中,Variables to be set in the environment,添加 NSZombieEnabled,并设定为 YES,点击选中复选框启用此变量。

 

 

这样,运行上述 Objective-C 时会看到控制台输出:

Untitled[3646:a0f] *** -[CFString release]: message sent to deallocated instance 0x10010d340

 

 

这条消息对于定位问题有很好的提示作用。但是很多时候,只有这条提示是不够的,我们需要更多的提示来帮助定位问题,这时候再加入 MallocStackLogging 来启用malloc记录。

 


当错误发生后,在终端执行:

 

malloc_history ${App_PID} ${Object_instance_addr} 则会获得相应的 malloc 历史记录,比如对于上一个控制台输出

Untitled[3646:a0f] *** -[CFString release]: message sent to deallocated instance 0x10010d340

则我们可以在终端执行

结果如下:

Buick-Wongs-MacBook-Pro:Downloads buick$ malloc_history 3646 0x10010d340
malloc_history Report Version: 2.0
Process: Untitled [3646]
Path: /Users/buick/Desktop/Untitled/build/Debug/Untitled
Load Address: 0×100000000
Identifier: Untitled
Version: ??? (???)
Code Type: X86-64 (Native)
Parent Process: gdb-i386-apple-darwin [3638]

Date/Time: 2011-02-01 15:07:04.181 +0800
OS Version: Mac OS X 10.6.6 (10J567)
Report Version: 6

ALLOC 0x10010d340-0x10010d357 [size=24]: thread_7fff70118ca0 start main objc_msgSend lookUpMethod prepareForMethodLookup _class_initialize +[NSString initialize] objc_msgSend lookUpMethod prepareForMethodLookup _class_initialize NXCreateMapTableFromZone malloc_zone_malloc
—-
FREE 0x10010d340-0x10010d357 [size=24]: thread_7fff70118ca0 start main objc_msgSend lookUpMethod prepareForMethodLookup _class_initialize _finishInitializing free

ALLOC 0x10010d340-0x10010d357 [size=24]: thread_7fff70118ca0 start main -[NSPlaceholderString initWithString:] objc_msgSend lookUpMethod prepareForMethodLookup _class_initialize _class_initialize +[NSMutableString initialize] objc_msgSend lookUpMethod prepareForMethodLookup _class_initialize NXCreateMapTableFromZone malloc_zone_malloc
—-
FREE 0x10010d340-0x10010d357 [size=24]: thread_7fff70118ca0 start main -[NSPlaceholderString initWithString:] objc_msgSend lookUpMethod prepareForMethodLookup _class_initialize _class_initialize _finishInitializing free

ALLOC 0x10010d340-0x10010d35f [size=32]: thread_7fff70118ca0 start main -[NSCFString substringWithRange:] CFStringCreateWithSubstring __CFStringCreateImmutableFunnel3 _CFRuntimeCreateInstance malloc_zone_malloc

这样就可以很快的定位出问题的代码片段了,注意输出的最后一行,,,这行虽然不是问题的最终原因,但是离问题点已经很近了,随着它找下去,八成就会找到问题。

当然,EXC_BAD_ACCESS 的定位方法还有很多,随着具体问题的不同而不同。欢迎各位讨论。

手把手教你搞定Pattern Recognition Letters的LaTeX投稿(附elsarticle.cls生成避坑指南) 本文详细指导如何在Pattern Recognition Letters(PRL)期刊上使用LaTeX进行投稿,特别针对elsarticle.cls文件的生成与常见问题提供避坑指南。从模板准备、文件上传到投稿后的验证,系统梳理全流程技术要点,帮助研究者高效完成学术论文投稿。 阅读详情

相关推荐

KEITHLEY 2182A + 6220/6221 系列测试系统软件

6221型与2182A型相结合,是业界最完整的差分电导测量解决方案

业余程序员小徐的博客 2985

Objective-C EXC_BAD_ACCESS

写程序遇到 Bug 并不可怕,大部分的问题,通过简单的 Log 或者 代码分析并不难找到原因所在。但是在 Objective-C 编程中遇到 EXC_BAD_ACCESS 问题的时候,通过简单常规的手段很难发现问题。这篇文章,给大家介绍一个常用的查找 EXC_BAD_ACCESS 问题根源的方法。 首先说一下 EXC_BAD_ACCESS 这个错误,可以这么说,90%的错误来源在于对一个已经...

weixin_30568591的博客 206

基于Spring Boot在线远程考试系统的设计与实现

结合先进的互联网技术,开发符合需求的软件,让数据内容管理不管是从录入的及时性,查看的及时性还是汇总分析的及时性,都能让正确率达到最高,管理更加的科学和便捷。目前的信息时代,对信息的管理趋于高效化,便捷化,这也是计算机大力普及所带来的便利,此程序软件在设备选用上,依靠的是比较大众的电脑设备,对电脑的配置没有过多要求,一般学校的计算机机房的电脑都可以满足程序开发需求,另外,开发出此款程序,让信息处理变得高效率,其所带来的高效益是远超程序开发的低成本的,因此程序开发的资金投入是可以忽略不计的。

ITbiyesheji的博客 1215

EXC_BAD_ACCESS(code=1问题的解决办法

今天在仿写微博APP的时候遇到了一个问题,编译运行,下拉刷新微博,一切正常,再次下拉刷新,程序就崩了,Xcode报错,EXC_BAD_ACCESS(code=1,花了好长时间才发现是哪里错了,现在在这里总结一些可能会到这这个错误产生的问题。当Xcode报错的时候会定位到某一行,但是却没有详细的信息,比如我的程序中,代码就定位到了 params[@"since_id"] = firstStatus.

ShorewB的博客 2万+

RS485设备联网避坑指南:塔石串口服务器在MODBUS平台中的3个关键配置项

本文针对塔石串口服务器在MODBUS物联网平台接入中的常见问题,详细解析了三个关键配置项:工作模式选择、远程端口与保活机制、寄存器映射与轮询策略。通过对比错误与正确配置案例,帮助工程师避开配置陷阱,实现RS-485设备的稳定、高效联网,提升批量部署的成功率与系统可靠性。

weixin_29281941的博客 405

Electron多窗口开发避坑指南:Pinia状态同步的3种解决方案对比

本文深入探讨了在Electron多窗口应用中实现Pinia状态同步的三种核心方案。针对Electron多窗口架构下状态隔离的挑战,文章对比了基础事件通信、共享存储以及智能Pinia插件等方案的优劣与适用场景,并提供了生产级的实现指南与选型建议,帮助开发者构建健壮高效的桌面应用。

spice的博客 479

什么是EXC_BAD_ACCESS以及如何调试

某些时候,你可能会遇到由EXC_BAD_ACCESS引起的崩溃。在这片文章中,你将学会什么是EXC_BAD_ACCESS,以及它是由什么引起的。我也将提出一些解决由EXC_BAD_ACCESS引起的bug的技巧。什么是EXC_BAD_ACCESS?一旦你理解了EXC_BAD_ACCESS的根本原因,你会更好地理解它这个含义模糊的名称。这里有一个简单的解释和一个更加专业的解释。让我们首先以这个简单的解

妙亦涵的博客 2万+

基于YOLOv8的人群聚集检测系统:含UI界面设计与数据集应用

人群聚集检测是智慧城市、公共安全和疫情防控等领域的重要任务。本文结合YOLOv8最新目标检测技术,设计并实现了一个高效的人群聚集检测系统,支持可视化UI界面操作,方便用户实时检测和分析视频中的人群密度。本文详细介绍了系统设计思路、使用的数据集、YOLOv8模型训练和推理过程,以及UI界面的开发与整合。最后通过实验验证了该系统的实用性和性能表现。更灵活的模型架构强化的特征融合网络(PAN++)自动混合精度训练支持支持多任务学习(目标检测+分类+分割)预训练模型丰富,适应多种应用场景。

YOLO 432

#Cocos Creator# 一次自定义引擎的实践

写在前边 首先,其实我不是很赞成自定义引擎的,如果能通过官方方法来解决问题,最好就不要自己修改引擎,主要原因有2: 1). 你没有引擎组更熟悉这些代码 2). 维护上比较麻烦 不过,偶尔遇到个别奇葩问题,或者想甩锅给引擎,你还是会需要查看甚至修改引擎代码来验证你的想法。 本文记录一下非常基础的自定义引擎过程。 全程参考Cocos Creator官方文档,网络正常的话,没有什么坑。h...

xuefujin的博客 2645

【ACP】2025-最新-疑难题解析- 练习二汇总

全球加速是优化公网访问的,负载均衡是分发流量的,公网 NAT 网关是处理公网 IP 的,高速通道是建私网连接但不直接提供固定私网地址功能。C 是客户端加密方式,D 是 ECS 云盘加密,都不属于 OSS 服务器端加密。某企业想使用云服务器 ECS + 负载均衡 SLB + 弹性伸缩 (Auto Scaling) 的架构搭建一个企业级门户网站,技术负责人对于负载均衡和弹性伸缩配合使用没有经验,于是将他理解的两种产品配合使用的一些技术细节列成了一个表单,并请作为架构师的您帮他做一下鉴别,以下哪些项是正确的?

jundao1997的专栏 293

番外篇第3集:多模态运维!让 AI 看懂 Grafana 图表并自动生成巡检报告

文章摘要 《多模态运维:让AI看懂Grafana图表并自动生成巡检报告》介绍了如何利用Qwen2.5-VL多模态模型解决传统运维巡检的痛点。文章指出人工查看Grafana监控图表存在效率低、易漏判、报告编写耗时等问题,提出通过Grafana Render API和多模态AI技术实现自动化巡检方案。 主要内容包括: 环境准备:配置Qwen2.5-VL多模态模型和Grafana访问权限 测试验证:展示模型准确识别图表类型、指标数值和异常趋势的能力 技术实现:封装Grafana截图API客户端,支持面板截图和数据

qq_2937655951的博客 108

XCode报错Thread 1: EXC_BAD_ACCESS (code=2, address=0x....)

XCode报错Thread 1: EXC_BAD_ACCESS (code=2问题描述:解决方法: 问题描述: 执行任何代码前单元测试崩溃 在Xcode中运行单元测试时崩溃:Thread 1: EXC_BAD_ACCESS (code=2, address=0x…) 解决方法: Product -> Scheme -> edit scheme -> info中取消勾选Debug executable ...

THEGREATHXY的博客 5152

RH850从0搭建Autosar开发环境【3X】- Davinci Configurator之OS模块配置详解(中)

RH850从0搭建Autosar开发环境【3X】- Davinci Configurator之OS模块配置详解(中)

weixin_42412049的博客 1513

EXC_BAD_ACCESS 解决办法

1,今天把工程转换成了ARC,转换完之后,运行程序直接就crash掉了。未转换的时候使用完全没有问题的。 crash的地方是:在登陆的界面,调用发送登陆指令的时候死掉     [[NSNotificationCenterdefaultCenter]postNotificationName:@"loginCommand"object:packet];一直死在这里, 刚开始怀疑是不是因为

taylor的专栏 6435

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

解决EXC_BAD_ACCESS错误的一种方法--NSZombieEnabled

我们做iOS 程序开发时经常用遇到 EXC_BAD_ACCESS 错误导致 Crash,出现这种错误时一般 Xcode 不会给我们太多的信息来定位错误来源,只是在应用 Delegate 上留下像Thread 1: Program received signal:"EXC_BAD_ACCESS",让问题无从找起。 比如你对已释放的对象发送消息时就会出现,EXC_BAD_ACCESS,再如relea

程序人生 10万+

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

解决 EXC_BAD_ACCESS 错误

出现 EXC_BAD_ACCESS  错误,给你的错误提示就这个,如何根本没法知道哪里错误了,其实还是有方法知道的, 做如下设置: Project -&gt; Edit active executable -&gt;Argument  添加如下四个参数 NSDebugEnabled NSZombieEnabled MallocStackLogging  MallocStackLo...

hotfm的专栏 330

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

ios 调试技巧收藏 一 解决EXC_BAD_ACCESS错误的一种方法--NSZombieEnabled

我们做iOS 程序开发时经常用遇到 EXC_BAD_ACCESS 错误导致 Crash,出现这种错误时一般 Xcode 不会给我们太多的信息来定位错误来源,只是在应用 Delegate 上留下像Thread 1: Program received signal:"EXC_BAD_ACCESS",让问题无从找起。 比如你对已释放的对象发送消息时就会出现,EXC_BAD_ACCESS,再

liangguo03的专栏 1万+

如何解决EXC_BAD_ACCESS?

You can often get information from the header files. For example: $ cd /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk $ find usr -name \*.h -exec f

依然风 | ios 2411

用NSZombieEnabled解决恼人的EXC_BAD_ACCESS错误(转)

用NSZombieEnabled解决恼人的EXC_BAD_ACCESS错误 On 03/30/2011, in iOS Dev, Mac-Dev, by G ...

dengxu4495的博客 149

用NSZombieEnabled解决恼人的EXC_BAD_ACCESS错误

转自:http://www.cocoachina.com/iphonedev/sdk/2011/0626/2980.html    有时开发者会遇到这样的问题:程序突然Crash,出现EXC_BAD_ACCESS错误。但是不是每次都Crash,Debug时最终基本停在objc-msgsend这里,十分令人费解。     首先解释下EXC_BAD_ACCESS,当你向已经释放的对象发送消息...

modun1986的专栏 219

使用Instruments解决EXC_BAD_ACCESS

http://www.cocoachina.com/bbs/read.php?tid=55526 这里有一篇关于使用NSZombieEnabled和MallocStackLogging查找EXC_BAD_ACCESS问题所在的文章。 http://www.cocoachina.com/macdev/objc/2011/0219/2661.html 现在要介绍的其实是为上述

水泽木兰 825

【转】解决EXC_BAD_ACCESS

解决EXC_BAD_ACCESS错误的一种方法--NSZombieEnabled http://blog.youkuaiyun.com/likendsl/article/details/7566305

weixin_33739646的博客 121
上一篇: iOS开发之Objective-C与JavaScript交互操作
下一篇: C++中的static关键字
qtcreatorlinux
博客等级 码龄15年 17粉丝 22原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值