我的应用程序在Lion从睡眠状态唤醒时崩溃。 问题似乎是背景线程正在寻找天气信息。 我不确定,但我认为崩溃日志告诉我自动释放池正在弹出不再存在的对象,有人可以帮我确认吗?
以下是崩溃日志的相关详细信息:
进程:myApp [14187]标识符:myApp版本:
??? (???)代码类型:X86-64(Native)父进程:launchd [224]日期/时间:2011-08-24 18:58:00.581 -0400操作系统版本:Mac OS X 10.7.1(11B26)报告版本:9
坠毁线程:7
异常类型:EXC_BAD_ACCESS(SIGSEGV)异常代码: KERN_INVALID_ADDRESS位于0x0000000000000010
应用程序特定信息:objc [14187]:垃圾收集是 OFF
线程7崩溃:0 libobjc.A.dylib
0x00007fff9321700b(匿名 namespace):: AutoreleasePoolPage :: pop(void *)+ 385 1
com.apple.CoreFoundation 0x00007fff961306a5 CFAutoreleasePoolPop + 37 2 com.apple.Foundation
0x00007fff969350d7 - [NSAutoreleasePool drain] + 154 3
com.piso13.opusDomini 0x00000001000acb91 - [天气 internalStart] + 417 4 com.apple.Foundation
0x00007fff9698b1ea - [NSThread main] + 68 5 com.apple.Foundation
0x00007fff9698b162 NSThread _main + 1575 6 libsystem_c.dylib
0x00007fff90b068bf _pthread_start + 335 7 libsystem_c.dylib
0x00007fff90b09b75 thread_start + 13
以下是我的天气内部开始代码:
-(void)internalStart{
pool = [[NSAutoreleasePool alloc] init];
forecast = FALSE;
liveweather = FALSE;
NSString *query = [self generateQuery];
if (query == nil) {
[pool drain];
return;
}
XmlWrapper * xmlWrapper = [[XmlWrapper alloc] initWithQuery:query delegate:self name:@"liveweather"];
[xmlWrapper release];
query = [self generateForecastQuery];
xmlWrapper = [[XmlWrapper alloc] initWithQuery:query delegate:self name:@"forecast"];
[xmlWrapper release];
[pool drain];
}
我是否应该打电话给[池排水]?
答案 0 :(得分:4)
创建具有绑定生命周期和显式范围的自动释放池。
在这种情况下,您将自动释放池存储在ivar(假定的)中。
将其置于方法的本地,如下所示:
- (void)internalStart
{
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
//...
[pool drain], pool = nil;
}
通常引入的问题是:
1)自动释放池是基于堆栈的(推送和弹出池)。通过抓住它,您可以轻松搞乱堆栈顺序。
2)如果此类在多线程上下文中运行,则当您从多个线程推送和弹出池时,很容易泄漏池或破坏堆栈顺序。
3)您还可能在多线程上下文中泄漏池
答案 1 :(得分:3)
不幸的是,autoreleasepool崩溃是最难调试的。从静态分析器开始,可以找到一些东西。
然后启用NSZombies。
你的XmlWrapper
对象有点奇怪。为什么一旦创建就立即释放它?这是NSURLConnection
的包装吗?您仍应保留该对象,以便在释放此对象时可以取消它或清除其委托。
确保您使用所有ivars的访问器,而不是直接访问它们。根据我的经验,直接访问init
和dealloc
以外的ivars是造成这类崩溃的首要原因。