2

Lion がスリープから復帰すると、アプリがクラッシュします。問題は、天気情報を探しているバックグラウンド スレッドにあるようです。よくわかりませんが、クラッシュ ログは、自動解放プールが存在しないオブジェクトをポップしていることを示していると思います。誰かがこれを確認するのを手伝ってくれますか?

クラッシュ ログに関連する詳細は次のとおりです。

プロセス: myApp [14187] 識別子: myApp バージョン:
??? (???) コード タイプ: X86-64 (ネイティブ) 親プロセス: launchd [224]

日時: 2011-08-24 18:58:00.581 -0400 OS バージョン: 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
0x00007fff969350d7 154 3
com.piso13.opusDomini 0x00000001000acb91 -[Weather 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 スレッド開始 + 13

Weather Internal Start のコードは次のとおりです。

-(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];

}

[プールドレイン] に電話する必要がありますか?

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 のクラッシュはデバッグが最も難しいものの 1 つです。いくつかのものを見つけることができる静的アナライザーから始めます。

次にNSZombiesをオンにします。

あなたのXmlWrapperオブジェクトは少し奇妙です。作ったらすぐにリリースするのはなぜですか?これはラッパーNSURLConnectionですか?このオブジェクトが解放されたときに、オブジェクトをキャンセルしたりデリゲートをクリアしたりできるように、オブジェクトを保持する必要があります。

直接アクセスするのではなく、すべての ivar に対してアクセサーを使用していることを確認してください。外部の ivar への直接アクセスinitdealloc、私の経験では、この種のクラッシュの最大の原因です。

于 2011-08-25T18:29:07.677 に答える