3

解決済み(私は思う): VC が (dealloc で) ポップされた後、ASIHTTPRequest デリゲート/NSOperationQueue デリゲートを nil に設定します。

始める前に、この質問は似ていますが同じではありません。

私のアプリはリリース間近ですが、これは開発中に存在した唯一の永続的なバグです。誰かにアプリをデモするときに発生した唯一のバグでもあり、このバグが原因でアプリが終了するため、非常に恥ずかしいです。誰かがこれに対する修正を (完全に) 見つけることができれば、私はまともなサイズの報奨金を授与します.


質問の開始:

基本的に、このバグは、ASIHTTPRequestrequestFinishedがゾンビであるオブジェクトに対してセレクターを呼び出そうとしたときに発生します。

周囲を見渡すと、ASIHTTPRequest は、セレクターをゾンビに送信する場合に、ゾンビではない同様のオブジェクトに送信するように見えます。送信先のコントローラーの CALayer にセレクターを送信することは非常に一般的だと聞きましたが、私の UINavigationButton にも送信されます!? - とにかく、これの効果は例外をスローすることです。

「requestFinished」セレクターを呼び出そうとすると、ASIHTTPRequest クラス内で問題が発生します。

[queue performSelector:@selector(requestFinished:) withObject:self];

そのコード行は失敗したものです - 私を困惑させるのはなぜですか? [self retain]私がリンクした質問について、OPはビューコントローラーから呼び出すことで修正したと言いました。きっとそうじゃない?

構造

私の ASIHTTPRequest が機能する方法は、アプリケーション デリゲート内に存在する downloadQueue (NSOperationQueue) に追加されることです。私のアプリの構造/スタイルは、主にこのサンプル コードに基づいています。このサンプル コードは、非常によく似た処理を行いますが、flickr RSS フィードを使用します。

ASIHTTPRequest を使用する私のアプリのセクションは、Web カメラ ビューアーです。3 つの Web カメラを表示するテーブル ビューを備えたナビゲーション コントローラーがあります。これらの画像は JPEG で、30 秒ごとに静的ファイル (リモート サーバー上) に更新されます。このテーブル ビュー内のセルはカスタムであり、それぞれが独自の ASIHTTPRequest をロードします。セルはそれぞれの画像をダウンロードして表示します。

これが私が作成したメソッドで、各セルで呼び出されます。

- (void)loadURL:(NSURL *)url {
    ASIHTTPRequest *request = [[ASIHTTPRequest alloc] initWithURL:url];
    [request setDelegate:self];
    [request setDidFinishSelector:@selector(requestDone:)];
    [request setDidFailSelector:@selector(requestWentWrong:)];
    NSOperationQueue *queue = [[MyAppDelegate sharedAppDelegate] downloadQueue];
    [queue addOperation:request];
    [spinner startAnimating];
    [self addSubview:spinner];
    [request release];  
}

これらのセルの 1 つを選択すると、ユーザーは詳細ビューに移動し、そこで ASIHTTPRequest の別のインスタンスが読み込まれ、選択した Web カメラの画像がダウンロードされます。

バグの発生方法

私のアプリの通常の「穏やかな」使用法では、正常に動作します。この問題は、これらのビュー間 (ルート Web カメラ ビューと詳細 Web カメラ ビューの間) で急速なプッシュとポップが発生した場合に発生します。詳細ビューに入り、進行状況バーが動き始め、ルートに再びポップすると、最も頻繁に発生します。これにより、コントローラーがアクティブではないため、ASIHTTPRequest が終了し、コントローラーを呼び出そうとすると失敗することがわかりました。

クラッシュログ

Exception Type:  EXC_BAD_ACCESS (SIGBUS)
Exception Codes: KERN_PROTECTION_FAILURE at 0x00000480
Crashed Thread:  0

Thread 0 Crashed:
0   libobjc.A.dylib                 0x30183f24 objc_msgSend + 24
1   iCompton                        0x0003c4d4 0x1000 + 242900
2   CoreFoundation                  0x35ea3f72 -[NSObject(NSObject) performSelector:withObject:] + 18
3   iCompton                        0x00029082 0x1000 + 163970
4   CoreFoundation                  0x35ea3f72 -[NSObject(NSObject) performSelector:withObject:] + 18
5   Foundation                      0x33fd3e66 __NSThreadPerformPerform + 266
6   CoreFoundation                  0x35ebc8ca __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 8
7   CoreFoundation                  0x35e8cec6 __CFRunLoopDoSources0 + 378
8   CoreFoundation                  0x35e8c6f2 __CFRunLoopRun + 258
9   CoreFoundation                  0x35e8c504 CFRunLoopRunSpecific + 220
10  CoreFoundation                  0x35e8c412 CFRunLoopRunInMode + 54
11  GraphicsServices                0x35261d1c GSEventRunModal + 188
12  UIKit                           0x33865574 -[UIApplication _run] + 580
13  UIKit                           0x33862550 UIApplicationMain + 964
14  iCompton                        0x00002b92 0x1000 + 7058
15  iCompton                        0x00002b44 0x1000 + 6980

  • ここまで読んでくれてありがとう!
  • 答えてくれたらもっとありがとう
  • あなたが私の問題を解決すれば報奨金:)
4

3 に答える 3

6

詳細ビューに入り、進行状況バーが動き始め、ルートに再びポップすると、最も頻繁に発生します。これにより、コントローラーがアクティブではないため、ASIHTTPRequest が終了し、コントローラーを呼び出そうとすると失敗することがわかりました。

私はあなたがこれについて正しいと思います。

ルートコントローラー (または他のコントローラー) にポップするときに、ASIHTTPRequest をキャンセルする必要があります。リクエストをキャンセルする前に、delegatenil に設定する必要があります。または使用できますclearDelegatesAndCancel

おそらくこれには、View Controller でリクエストへの参照を保持する必要がありますが、それは問題ではありません。

ポップされた UIViewController の検出に関する興味深い SO の質問/回答はこちらです。

于 2011-07-28T20:50:01.093 に答える
0

この問題を解決した方法は次のとおりです。viewControllerのメソッド でdelegate未処理ASIHTTPRequestの を設定します。nildealloc

これにより、viewControllerASIHTTPRequestがナビゲーション スタックから取り出されて'd.didFinishSelectordidFailSelectordealloc

注意:ASIHTTPRequestメソッドは を非同期的に呼び出すcancelAllOperations 可能性があります。didFailSelectorこの場合、もはや存在しない viewController でセレクターが呼び出される可能性があります。

于 2011-08-25T20:54:48.500 に答える
0

ライブ アプリで NSZombieEnabled を使用しないでください。メモリが解放されることはありません。開発中以外はオフにする必要があります。急速なプッシュとプルはおそらくメモリを使い果たし、メモリ警告を引き起こし、物事が解放され、解放されます。ただし、クラッシュ ログを投稿するまではわかりません。

于 2011-07-28T20:11:58.563 に答える