我们做iOS 程序开发时经常用遇到 EXC_BAD_ACCESS 错误导致 Crash,出现这种错误时一般 Xcode 不会给我们太多的信息来定位错误来源,只是在应用 Delegate 上留下像Thread 1: Program received signal:"EXC_BAD_ACCESS",让问题无从找起。
比如你对已释放的对象发送消息时就会出现,EXC_BAD_ACCESS,再如release 的对象再 release,release 那些autorelease 的对象等也会报这样的错。默认设置下 Xcode 不会给你定位具体是哪一行代码,不该去使用已释放的对象,或者release 用错了。
比如 UIViewController 子类中这样的代码:
- static NSMutableArray*array;
- -(void)viewDidLoad
- {
- [superviewDidLoad];
- array= [[NSMutableArray alloc]initWithCapacity:5];
- [array release];//释放掉该数组
- }
- - (void)viewWillAppear:(BOOL)animated{
- [array addObject:@"Hello"];//使用释放掉的数组
- }
上面的代码就会出现EXC_BAD_ACCESS 错误,但我执行时 Xcode 一出错却是定位在我 在 AppDelegate 的 application:didFinishLaunchingWithOptions: 方法上的某行了,如果代码量 多了,要查找具体问题非常难,但凭经验了。
不过NSZombieEnabled 环境变量可以帮我们的忙,就是当 设置NSZombieEnabled环境变量后,一个对象销毁时会被转化为_NSZombie,设置NSZombieEnabled后,当你向一个已经释 放的对象发送消息,这个对象就不会向之前那样Crash或者产生一个难以理解的行为,而是放出一个错误消息,然后以一种可预测的可以产生debug断点的 方式消失, 因此我们就可以找到具体或者大概是哪个对象被错误的释放了。
对 Xcode 设置了NSZombieEnabled 之后,Xcode 会明确定位在行[array addObject:@"Hello"],然后控制台下报的错误信息是:
*** -[__NSArray addObject:]:message sent to deallocated instance 0x6557370
如何设置 NSZombieEnabled 呢,在 Xcode3 和 Xcode4 下设置不一样,Xcode4 下设置很简单。
Xcode3 下 NSZombieEnabled 设置方法如下:
1. 在XCode左边那个Groups& Files栏中找到Executables,双击其中的一项,或者右键Get Info;
2. 切换到Arguments
3. 这里一共有两个框,在下面那个Variables to be set in theenvironment:点+号添加一项,Name里填NSZombieEnabled,Value填Yes,要保证前面的钩是选中的。
Xcode4 下设置 NSZombieEnabled 的方法:
你可以点击 Xcode4 菜单 Product -> Edit Scheme-> Arguments, 然后将点击”加号”, 将 NSZombieEnabled 参数加到Environment Variables 窗口中, 后面的数值写上 ”YES”.
或者在 Xcode4 菜单 Product -> EditScheme -> Diagnostics 设置窗口中直接勾上Enable ZombieObjects 即可,Xcode 可用 cmd+shift+< 进到这个窗口。
Xcode4 已经考虑到了现在的要求,所以提供了更便捷的设置的方式,你也可以在这个窗口中设置其他一些参数,你肯定能由此获得更多的帮助信息。
另外再说一下,如果没有为 Xcode 设置 NSZombieEnable,像下面的代码或许可以正确执行,打印出你所期望的结果“Hello”
- static NSMutableArray*array;
- -(void)viewDidLoad
- {
- [super viewDidLoad];
- array= [[NSMutableArray alloc]initWithCapacity:5];
- [array release];
- [array addObject:@"Hello"];//之所以不会crash,是在于事件周期未完,内存回收机制还没有执行,没有真正的回收掉array的对象内存。
- NSLog(@"%@",[array objectAtIndex:0]);
- }
但是一旦加上了NSZombieEnable 设置,上面的代码行 [array addObject:@"Hello"] 也将无法投机取巧了,同样会得到错误提示:
*** -[__NSArrayM addObject:]:message sent to deallocated instance 0x6557370
即使该array 所指向的内存还是原来的数据也不能逃脱掉 NSZombieEnable 的法眼。也就是之所以未设置 NSZombieEnable 时上面代码能得到正确结果,是因为,虽然 [array release] 是标记为释放掉该内存块,但是后面使用 array 时,因为该指针指向的内存数据未被覆盖,所以未出错,这和C++ 的指针 delete 后的效果是一样的。
- CocoaDev,个人觉得讲Cocoa技术十分专业的网站之一,下面的链接详细讲了讲NSZombieEnable的原理。http://www.cocoadev.com/index.pl?NSZombieEnabled
- 苹果官方的Mac OS X Debugging Magic,详细讲述了最为一个高级苹果程序员应该具备的调试技巧 http://developer.apple.com/library/mac/#technotes/tn2004/tn2124.html
- 其实还可以在Instruments中开启NSZombie选项,这样就可以在Instruments中直接查看crash时候的callstack了:http://www.markj.net/iphone-memory-debug-nszombie/
最后提醒NSZombieEnabled只能在调试的时候使用,千万不要忘记在产品发布的时候去掉,因为NSZombieEnabled不会真正去释放dealloc对象的内存,一直开启后果可想而知,自重!
相关推荐
《iOS植物大战僵尸》是一款基于iOS平台的经典塔防游戏,深受玩家喜爱。在这个项目中,开发者运用了多种iOS开发技术和游戏设计原则,构建了一个既有趣又有挑战性的游戏环境。接下来,我们将深入探讨该项目中涉及的...
iOS开发调试技巧是指在iOS平台上进行软件开发过程中,为了发现和修正代码中的错误而使用的一系列方法和工具的总称。在iOS开发中,调试是一个非常重要的环节,它能够帮助开发者理解程序运行的内部状态,以便找出问题...
在iOS开发过程中,调试是必不可少的一环,尤其是在对新版本系统进行适配和优化时。本文将详述针对iOS 10.3 (14E269)真机调试的相关知识点,帮助开发者更好地理解这一特定版本的系统特性和调试技巧。 首先,iOS 10.3...
iOS安全近年来已成为一个热门话题。很多人开始讨论iOS上的安全设计和利用。但有时候我们只是需要更多的乐趣。我们将从测试攻击的视角做一些更有意思的事情,而...我们将用一个示例向您展示iOS僵尸网络的一些可行性。
iOS平台的应用程序调试与分析在安全领域尤为重要,因为它可以帮助我们发现潜在的安全风险,如DDoS攻击防护、僵尸网络检测以及企业安全策略的实施。通过对应用程序的深入分析,可以识别并修复安全漏洞,防止恶意软件...
《Cocos2dx游戏开发:基于“植物大战僵尸”在iOS平台上使用Xcode》 Cocos2dx是一款开源的游戏开发框架,它基于C++,同时提供了Lua和JavaScript的绑定,使得开发者可以方便地进行跨平台游戏开发。在这个项目中,我们...
在iOS开发中,EXC_BAD_ACCESS错误是一种常见的运行时错误,通常是因为程序尝试访问已被释放的内存地址导致的。当程序尝试访问一个已经释放的对象时,系统就会抛出EXC_BAD_ACCESS错误,这在C语言中通常被理解为使用了...
关于内存优化的部分,用户指南提到了多种内存问题的检测方法,包括使用Activity Monitor模板检查内存使用情况、Allocations模板查找废弃内存、Leaks模板定位内存泄漏以及Zombies模板清除僵尸对象。这些工具对于识别...
游戏在苹果设备上的运行需要专门针对iOS系统的优化,这通常涉及到对Swift或Objective-C等语言的应用,以及利用Xcode这样的集成开发环境来构建和调试。此外,还需要考虑到iOS设备的硬件特性,比如不同的屏幕尺寸和...
《cocos2dx 3.0 植物大战僵尸》是一个基于Cocos2dx 3.0游戏引擎开发的项目,它复刻了经典游戏《植物大战僵尸》的玩法和资源。Cocos2dx是一个开源的游戏开发框架,用C++编写,支持多平台,包括iOS、Android以及...
标题中的“僵尸信号SIGABRT或EXC_BAD_ACCESS”是iOS开发中常见的错误类型,主要与内存管理和对象生命周期有关。这两个错误通常出现在Objective-C或Swift编程中,涉及到内存泄漏、过早释放对象或者试图访问已经释放的...
10. **测试与发布**:在开发过程中,需要进行不断的测试和调试,确保游戏的稳定性和兼容性。最后,通过Unity的构建功能,我们可以将游戏打包成不同平台的应用,如iOS、Android或PC。 通过这份笔记和源代码,开发者...
Instruments是一款由苹果公司开发的高级调试与性能分析工具,主要用于检测iOS和macOS应用的性能瓶颈。它能够帮助开发者识别并解决诸如内存泄漏、CPU占用过高、磁盘I/O效率低下等问题,是提高应用性能、优化用户体验...
3. 对于iOS平台,App Sandboxing和App Store审核机制也是保障游戏安全的重要环节。 综上所述,《植物大战僵尸》的底层安全分析涵盖了从高级语言到底层硬件的多个层次,涉及到编程技术、安全策略和平台特性。深入...
面试者需解释如何启用僵尸模式以及它如何帮助调试内存问题。 7. **设计一个日志系统**: - 日志系统需要考虑日志级别、存储、检索、过滤和压缩等因素。面试者应讨论如何确保日志的可读性、可追溯性,并考虑性能和...
3. Qt Creator:Qt框架通常与Qt Creator集成开发环境一起使用,该IDE提供了一个完整的开发环境,包括代码编辑器、构建工具、调试器和版本控制系统,便于开发人员编写、测试和调试代码。 4. GUI设计:Qt框架提供了...
Instruments 是一款强大的性能分析和测试工具,它是 Xcode 集成开发环境(IDE)的一部分,专为 iOS、watchOS、tvOS 和 macOS 应用程序的开发和调试设计。这个工具提供了丰富的功能,帮助开发者深入理解应用的行为和...
在iOS开发中,内存管理是至关重要的,因为它直接影响到应用的性能和稳定性。Objective-C和Swift都使用了...学习如何处理僵尸对象、避免循环引用,以及有效地使用弱引用和强引用,都是成为专业iOS开发者不可或缺的知识。
注意,`info malloc-history`命令只适用于gdb调试器,并且只在iOS模拟器上有效,不支持真机调试。因此,确保在Xcode的Scheme设置中,Info tab中的Console Output选择为gdb。 通过以上步骤,开发者可以更有效地定位...