2

私はこれがどのように起こったのか本当に途方に暮れています。ARCを使用したアプリがあります。私のビューコントローラのほとんどはNSNotificationsに登録します。すべての登録はメインスレッドで行われます。

メモリ警告が発生すると、非表示の各タブに使用されているナビゲーションコントローラはゼロになり、その結果、割り当てが解除されます。この場合、1つのナビゲーションコントローラーとそのビューコントローラーの割り当てが解除され、ビューコントローラーがdeallocメソッド中にアプリをクラッシュさせました。

具体的には、すべてのNSNotificationCenter通知から自分自身を削除していました。

Deallocメソッドもメインスレッドで実行されたため、これがスレッドの問題になる可能性があるかどうかはわかりません。

クラッシュしたラインは-[SearchTabViewController dealloc] (SearchTabViewController.m:44)

コードのその行は次のとおりです。[[NSNotificationCenter defaultCenter] removeObserver:self];

実際のクラッシュの理由はobjc_msgSend、割り当てが解除されたオブジェクトを参照しているようです。

これに伴う問題は、ここで送信されるメッセージが2つしかないことです。クラスdefaultCenterへのメッセージNSNotificationCenter(クラスであるため無効な参照になることはありません)とremoveObserver:デフォルトのセンターオブジェクトへのメッセージ(これは、シングルトン)。

参照されている他の唯一のオブジェクトはselfです。これは、そのオブジェクトの「dealloc」メソッドを使用しているため、まだ割り当てを解除できません...基本的にこのクラッシュは発生しないはずです。

ここに欠けているものはありますか?以下のクラッシュログの関連部分:


Exception Type:  SIGSEGV
Exception Codes: SEGV_ACCERR at 0xe0000008
Crashed Thread:  0

Thread 0 Crashed:
0   libobjc.A.dylib                     0x000035b0 objc_msgSend + 16
1   Anghami Beta                        0x000c7473 -[SearchTabViewController dealloc] (SearchTabViewController.m:44)
2   CoreFoundation                      0x00003311 CFRelease + 101
3   CoreFoundation                      0x0000d95d -[__NSArrayM dealloc] + 141
4   Anghami Beta                        0x0033e73f -[EX2NavigationController .cxx_destruct] (EX2NavigationController.m:51)
5   libobjc.A.dylib                     0x00007f3d object_cxxDestructFromClass(objc_object*, objc_class*) + 57
6   libobjc.A.dylib                     0x000050d3 objc_destructInstance + 35
7   libobjc.A.dylib                     0x000053a7 object_dispose + 15
8   UIKit                               0x000cec89 -[UIViewController dealloc] + 1181
9   CoreFoundation                      0x00003311 CFRelease + 101
10  CoreFoundation                      0x0000da13 -[__NSArrayI dealloc] + 79
11  libobjc.A.dylib                     0x00005489 (anonymous namespace)::AutoreleasePoolPage::pop(void*) + 169
12  CoreFoundation                      0x00005441 _CFAutoreleasePoolPop + 17
13  CoreFoundation                      0x00095f41 __CFRunLoopRun + 1297
14  CoreFoundation                      0x00008ebd CFRunLoopRunSpecific + 357
15  CoreFoundation                      0x00008d49 CFRunLoopRunInMode + 105
16  GraphicsServices                    0x000052eb GSEventRunModal + 75
17  UIKit                               0x00057301 UIApplicationMain + 1121
18  Anghami Beta                        0x0000334d main (main.m:17)
4

1 に答える 1

3

そのため、クラッシュログは誤解を招くものであることが判明しました。ゾンビオブジェクトを有効にしてデバッガーに接続しているときに、最終的にそれを実現することができました。クラッシュの実際の原因は、このコントローラーをデリゲートとして持つローダーオブジェクトであり、コントローラーの割り当てが解除された後、デリゲートメソッドの1つを呼び出そうとしました。

現在deallocで、ローダーのデリゲートを無効にし、アクティブな場合はロードをキャンセルします。これ以上クラッシュすることはありません。


また、このクラッシュはシミュレーターでは発生しませんでしたが、デバイスではほぼ毎回発生したことは注目に値します。したがって、奇妙なメモリエラーを追跡する場合、残念ながら、ゾンビーズインスツルメントは、アプリをシミュレータで実行する必要があるため、常に実行可能なツールとは限りません。

したがって、次善の策は、[スキームの編集]に移動し、そこでゾンビオブジェクトを有効にしてから、デバイス上でビルドして実行し、クラッシュするのを待つことです。この方法では完全な保持/解放履歴を取得することはできませんが、この場合のように、他の方法ではとらえどころのない問題を追跡するのに十分な情報を提供できます。

于 2012-10-16T22:56:20.830 に答える