2011-08-25 194 views
2

我的应用程序在Lion上崩溃时,它从睡眠中醒来。 这个问题似乎与后台线程正在寻找天气信息。 我不知道,但我觉得崩溃日志告诉我,自动释放池弹出不再有对象,有人可以帮助我确认这一点?帮助崩溃日志

这里是崩溃日志有关的详情:

过程:对myApp [14187]标识符:对myApp版本:
??? (???)编码类型:X86-64(母语)父进程:的launchd [224]

日期/时间:2011-08-24 18:58:00.581 -0400 OS版本:的Mac OS X 10.7 0.1(11B26)报告版本:9

崩溃螺纹:7

异常类型:EXC_BAD_ACCESS(SIGSEGV)异常代码: KERN_INVALID_ADDRESS在0x0000000000000010

特定应用信息:objc [14187]:垃圾收集是 OFF

螺纹7毁损:0 libobjc.A.dylib
0x00007fff9321700b(匿名 命名空间):: AutoreleasePoolPage ::弹出(无效*)+ 385 1
com.apple.CoreFoundation 0x00007fff961306a5 CFAutoreleasePoolPop + 37 2 COM。 apple.Foundation
0x00007fff969350d7 - [NSAutoreleasePool漏极] + 154 3
com.piso13.opusDomini 0x00000001000acb91 - [天气 internalStart] + 417 4 com.apple.Foundation
0x00007fff9698b1ea - [NSThread主] + 68 5 com.apple 。基础
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]?

+0

这里没有看起来错......你可以展示一些'generateForecastQuery'或'generateQuery'吗?或者,也许你的'XmlWrapper'类? – jtbandes

+0

你从哪里复制了该崩溃日志?这全是错误的。请将它从原始崩溃日志文件复制到〜/ Library/Logs文件夹中,并编辑您的问题以包含带有代码格式的文本。 –

+2

创建它们时立即释放您的XMLWrapper对象是一个红旗。你为什么做这个? –

回答

4

创建绑定的寿命和明确范围的自动释放池。

在这种情况下

,你存储在一个实例变量(假定)的自动释放池。

只是使它本地的方法,像这样:

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

,其通常引入的问题是:

1)自动释放池栈为基础(池压入和弹出)。通过抓住它,你可以轻松搞定堆栈顺序。2)如果此类在多线程上下文中运行,则当您从多个线程中推送和弹出池时,您可以轻松地泄漏池或销毁堆栈顺序。

3)也可能泄漏池在多线程环境

+3

更简单:当这个方法在两个不同的线程上运行时,每个线程将自己的自动释放池放入'pool'实例变量中 - 但由于实例变量按照定义* per-instance *,两个线程都将它们汇入同一个地方。只有一个胜利,然后两个线程都试图消耗同一个池。这是崩溃。 –

+0

彼得谢谢你这是崩溃....你能帮助我释放过早吗?这个xmlWrapper从互联网上读取信息,并在天气信息准备就绪时向委托人(呼叫者)发送消息。处理过程中xmlWrapper可能会被销毁吗? –

3

不幸的是,autoreleasepool崩溃是一些最难调试的。从静态分析器开始,它可以找到一些东西。然后打开NSZombies。你的XmlWrapper对象有点奇怪。为什么你一创建它就立即发布它?这是围绕NSURLConnection的包装吗?您仍然应该保持对象,以便在释放此对象时可以取消它或清除它的委托。

确保您使用所有ivars的访问器,而不是直接访问它们。根据我的经验,直接访问initdealloc之外的ivars是导致这类崩溃的首要原因。

+0

从您的意见中,我想我可能会很快发布xmlWrapper。 xmlwrapper将向代理(当前调用者)发送一条消息,表明信息已准备好阅读。在发送完委托消息之前,是否可以在内部处理过程中释放此对象? –