xcode 4.2 如何调试 EXC_BAD_ACCESS
来源:互联网 发布:我的体育老师卫视网络 编辑:程序博客网 时间:2024/06/10 08:56
打开NSZombieEnabled来调试EXC_BAD_ACCESS
在写iOS程序时,无论你是新手还是牛人,都有可能会碰到EXC_BAD_ACCESS。而此时你的debug area中不会显示任何信息可以来帮助你找出问题。此时就需要打开NSZombieEnabled来提供更多有用的信息。
在XCode 4.2中,有两种方法来打开NSZombie。
方法一,添加环境变量, 在菜单中,选择Product->Edit Schema, 选择Run (App Name), 在Arguments下面的Environment Variables中,添加NSZombieEnabled, Value值为YES。
方法二,打开Diagnostics, 同样在菜单中选择Product -> Edit Schema, 选择Run (App Name), 在Diagnostics下,打开Memory Management下的Enable Zombie Objects.
此时,在运行程序,就会显示哪个instance已经被release了,而你还向这个对象发消息。
当问题解决后,要将NSZombieEnabled设置为无效,不需要删除变量,将变量前的对号去掉就可以了
以下为转载内容 原文地址:http://www.cnblogs.com/shenyunjun420/archive/2011/08/04/2127464.html
第一次遇到 EXC_BAD_ACCESS , 然后程序崩溃,没有任何调试信息
上网一查是这样解释的
向已经释放的对象发送消息时会出现EXC_BAD_ACCESS。当出现错误时,通常会调用堆栈信息,特别是在多线程的情况下。
其实就是使用了野指针.
于是,我就按照教程(http://www.codza.com/how-to-debug-exc_bad_access-on-iphone) 在Xcode中打开executables
然后,打开信息面板中的Arguments面板
然后添加参数 NSZombiEnabled=YES, 这个参数值可以让GDB在发现使用已经释放的对象时给出一个有用信息
(Zombie 想起了植物大战僵尸....)
再次运行,GDB给出了出错消息 2011-01-11 01:00:00.299 VDic[342:20b] *** -[FMResultSet release]: message sent to deallocated instance 0x3d30f70
至此,我知道了是FMResultSet 释放过度
但是是哪个地方释放过度却不甚清楚
于是把 objc_exception_throw 和 -[NSException raise] 加入了断点列表
再次运行,发现错误定位到main函数...汗...这个还是太不精确了
为什么main函数是错误位置呢? 我突然想到了main 函数里有个内存池来维护使用自动回收机制的对象
那么错误定位到main 可能就是这个位置出了问题
int main(int argc, char *argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
int retVal = UIApplicationMain(argc, argv, nil, nil);
[pool release];
return retVal;
}
进一步的回忆Fundation 框架的内存管理机制, 我很显然是在某个地方release了本来应该自动回收的FMResultSet对象
这样我就能够定位一些位置了, 查找了下, 果然....
+ (NSMutableArray *) select: (NSString *) sql;
{
NSMutableArray *arr = [[NSMutableArray alloc] init];
FMResultSet *rs = [db executeQuery:sql];
while ([rs next]) {
[arr addObject:[rs resultDict]];
}
[rs close];
[rs release];
return arr;
}
rs是其它对象函数返回的结果,初始时引用计数为1,并被投入到自动释放池中
而我画蛇添足的release 则是一切灾难的根源,阿门
去调此句果然运行通过了.
请大声朗读以下 Cocoa Fundation内存释放原则
1. 通过分配或复制创建的对象保持计数1
2. 假设任何别的方法获取的对象保持计数1,而且在自动释放池中. 要想在当前执行范围外使用该对象,就必须保持它
3. 向集合添加对象时它就被保持,从集合移除对象时就被释放.释放集合对象会释放该集合中的所有对象
4. 确保有多少alloc,copy,mutableCopy或retain消息就有多少release或autorelease消息发送给该对象. 换句话说,确保你的代码平衡
5. 在访问方法设置属性,先保持,再释放 (ztime: 现在有@propperty , @synthesize 两个指令自动创建此代码)
6. 用@"..."结构创建的NSString对象是常量.发送release或retain并无效果
总体而言,Cocoa Fundation的内存管理还是非常简单清晰的,
MS的COM对象生存期管理一样是智能指针:)
打开NSZombieEnabled来调试EXC_BAD_ACCESS
在写iOS程序时,无论你是新手还是牛人,都有可能会碰到EXC_BAD_ACCESS。而此时你的debug area中不会显示任何信息可以来帮助你找出问题。此时就需要打开NSZombieEnabled来提供更多有用的信息。
在XCode 4.2中,有两种方法来打开NSZombie。
方法一,添加环境变量, 在菜单中,选择Product->Edit Schema, 选择Run (App Name), 在Arguments下面的Environment Variables中,添加NSZombieEnabled, Value值为YES。
方法二,打开Diagnostics, 同样在菜单中选择Product -> Edit Schema, 选择Run (App Name), 在Diagnostics下,打开Memory Management下的Enable Zombie Objects.
此时,在运行程序,就会显示哪个instance已经被release了,而你还向这个对象发消息。
上网一查是这样解释的
向已经释放的对象发送消息时会出现EXC_BAD_ACCESS。当出现错误时,通常会调用堆栈信息,特别是在多线程的情况下。
其实就是使用了野指针.
然后,打开信息面板中的Arguments面板
然后添加参数 NSZombiEnabled=YES, 这个参数值可以让GDB在发现使用已经释放的对象时给出一个有用信息
(Zombie 想起了植物大战僵尸....)
再次运行,GDB给出了出错消息 2011-01-11 01:00:00.299 VDic[342:20b] *** -[FMResultSet release]: message sent to deallocated instance 0x3d30f70
至此,我知道了是FMResultSet 释放过度
但是是哪个地方释放过度却不甚清楚
于是把 objc_exception_throw 和 -[NSException raise] 加入了断点列表
再次运行,发现错误定位到main函数...汗...这个还是太不精确了
为什么main函数是错误位置呢? 我突然想到了main 函数里有个内存池来维护使用自动回收机制的对象
那么错误定位到main 可能就是这个位置出了问题
int main(int argc, char *argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
int retVal = UIApplicationMain(argc, argv, nil, nil);
[pool release];
return retVal;
}
进一步的回忆Fundation 框架的内存管理机制, 我很显然是在某个地方release了本来应该自动回收的FMResultSet对象
这样我就能够定位一些位置了, 查找了下, 果然....
+ (NSMutableArray *) select: (NSString *) sql;
{
NSMutableArray *arr = [[NSMutableArray alloc] init];
FMResultSet *rs = [db executeQuery:sql];
while ([rs next]) {
[arr addObject:[rs resultDict]];
}
[rs close];
[rs release];
return arr;
}
rs是其它对象函数返回的结果,初始时引用计数为1,并被投入到自动释放池中
而我画蛇添足的release 则是一切灾难的根源,阿门
去调此句果然运行通过了.
请大声朗读以下 Cocoa Fundation内存释放原则
1. 通过分配或复制创建的对象保持计数1
2. 假设任何别的方法获取的对象保持计数1,而且在自动释放池中. 要想在当前执行范围外使用该对象,就必须保持它
3. 向集合添加对象时它就被保持,从集合移除对象时就被释放.释放集合对象会释放该集合中的所有对象
4. 确保有多少alloc,copy,mutableCopy或retain消息就有多少release或autorelease消息发送给该对象. 换句话说,确保你的代码平衡
5. 在访问方法设置属性,先保持,再释放 (ztime: 现在有@propperty , @synthesize 两个指令自动创建此代码)
6. 用@"..."结构创建的NSString对象是常量.发送release或retain并无效果
总体而言,Cocoa Fundation的内存管理还是非常简单清晰的,
MS的COM对象生存期管理一样是智能指针:)
对象释放后通常要把指针设为nil
- xcode 4.2 如何调试 EXC_BAD_ACCESS
- xcode 4.2 如何调试 EXC_BAD_ACCESS
- xcode 4.2 如何调试 EXC_BAD_ACCESS
- xcode 4.2 如何调试 EXC_BAD_ACCESS
- Xcode 5中调试 EXC_BAD_ACCESS
- Xcode调试出现exc_bad_access错误
- iphone如何调试EXC_BAD_ACCESS
- 如何调试EXC_BAD_ACCESS
- iPhone 如何调试 EXC_BAD_ACCESS
- iphone如何调试EXC_BAD_ACCESS
- 如何调试EXC_BAD_ACCESS
- XCode调试技巧之EXC_BAD_ACCESS中BUG
- 什么是EXC_BAD_ACCESS以及如何调试
- XCode调试技巧之EXC_BAD_ACCESS中BUG解决
- XCode调试技巧之EXC_BAD_ACCESS中BUG解决
- XCode调试技巧之EXC_BAD_ACCESS中BUG解决
- XCode调试技巧之EXC_BAD_ACCESS中BUG解决
- XCode调试技巧之EXC_BAD_ACCESS中BUG解决
- vb.net winform在panel中打开exe文件
- Linux系统各个目录的作用(中英文对照)
- u/cos红外学习模块总结
- git的那些工具
- hibernate 之 annotation
- xcode 4.2 如何调试 EXC_BAD_ACCESS
- MM模块常用T-code
- 谈谈Teechart在工业监控方面的应用实例
- 机器如何区分和判定指令和数据
- 解决SVN unable to load defalut SVN client错误
- iOS Block学习
- Objective-C数组小结
- dg主备库切换步骤
- js --> obj2str