2

我的应用程序从睡眠中醒来时在 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) 异常代码:0x0000000000000010 处的 KERN_INVALID_ADDRESS

应用程序特定信息:objc[14187]:垃圾收集已关闭

线程 7 崩溃:0 libobjc.A.dylib
0x00007fff9321700b(匿名命名空间)::AutoreleasePoolPage::pop(void*) + 385 1
com.apple.CoreFoundation 0x00007fff961306a5 CFAutoreleasePoolPop + 37 2 com.apple.Foundation
0x00007fff96930+NSreleaseDrain 154 3
COM.PISO13.OPUSDOMINI 0x00000001000CB91 - [天气INESITESTART] + 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];

}

我什至应该打电话给 [pool drain] 吗?

4

2 回答 2

4

创建具有绑定生命周期和显式范围的自动释放池。

在这种情况下,您将自动释放池存储在 ivar(假定)中。

只需将其设置为方法的本地,如下所示:

- (void)internalStart
{
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
    //...
    [pool drain], pool = nil;
}

通常引入的问题是:

1) 自动释放池是基于堆栈的(池被推送和弹出)。抓住它,你可以很容易地弄乱堆栈顺序。

2)如果这个类在多线程上下文中运行,当你从多个线程推送和弹出池时,你可以很容易地泄漏池或破坏堆栈顺序。

3)您还可以在多线程上下文中泄漏池

于 2011-08-25T18:11:11.977 回答
3

不幸的是,autoreleasepool 崩溃是最难调试的。从静态分析器开始,它可以找到一些东西。

然后打开NSZombies

你的XmlWrapper对象有点奇怪。为什么一创建就立即发布呢?这是一个包装NSURLConnection吗?您仍应保留该对象,以便在该对象被释放时取消它或清除其委托。

确保您为所有 ivars 使用访问器,而不是直接访问它们。根据我的经验,直接访问外部的 ivarsinitdealloc导致此类崩溃的第一大原因。

于 2011-08-25T18:29:07.677 回答