2

テスターの 1 人が次のクラッシュを報告しています。

0 APP_NAME_WAS_HERE 0x00074892 testflight_backtrace + 158
1 APP_NAME_WAS_HERE 0x000754bc TFSignalHandler + 244
2 libsystem_c.dylib 0x378ea7ec _sigtramp + 48
3 CoreFoundation 0x30ef42e6 CFRelease + 94
4 CoreFoundation 0x30f09a36 -[__NSArrayM removeObjectAtIndex:] + 294
5 CoreFoundation 0x30f4a65e -[NSMutableArray removeObjectsInRange:] + 90
6 APP_NAME_WAS_HERE 0x000570ca -[StoryViewController rewindToChunkIndex:] + 558
7 APP_NAME_WAS_HERE 0x00057396 -[StoryViewController restartChapter] + 22

残念ながら、クラッシュを再現することはできません。TestFlight 経由で送信されたクラッシュ ログのみを取得しています。

デバッグ ログを受信して​​、 が動作中removeObjectsInRangeの の有効な範囲を確実に受信していることを確認しNSMutableArrayました。(さらに、それはシグナルを発生させるのではなく、例外を発生させますよね?)

私の唯一の考えは、オブジェクトが二重解放されているということですが、ARC がオンになっているとこれがどのように可能になるのかわかりません。

削除されるオブジェクトはUIViewサブクラスであり、事前にそれらの一部またはすべてがスーパービューから削除されている可能性があることに注意してください。したがって、この段階でリリースされたとしても驚かないでしょうが、なぜそれが原因でクラッシュするのか理解できません!

編集: 過剰にリリースされたオブジェクトであることを確認するために、(ARC 環境で強制的にリリースするために使用して) オブジェクトを人為的に過剰にリリースしCFRelease(__bridge (CFTypeRef) obj)て、それが生成するクラッシュ ログのタイプを確認しました。残念ながらちょっと違うので、やっぱりオーバーリリースじゃないのかな?何かの落書きではないでしょうか。

明確な過剰リリースは次のようになります。

Exception Type:  EXC_CRASH (SIGABRT)
Exception Codes: 0x00000000, 0x00000000
Crashed Thread:  0

Thread 0 name:  Dispatch queue: com.apple.main-thread
Thread 0 Crashed:
0   libsystem_kernel.dylib          0x369c732c __pthread_kill + 8
1   libsystem_c.dylib               0x36c20208 pthread_kill + 48
2   libsystem_c.dylib               0x36c19298 abort + 88
3   libsystem_c.dylib               0x36bd437a free + 374
4   libobjc.A.dylib                 0x375e4d72 object_dispose + 14
5   CoreFoundation                  0x362e9618 -[NSObject dealloc] + 76
6   UIKit                           0x310323a8 -[UIView dealloc] + 620
7   libobjc.A.dylib                 0x375e416e _objc_rootRelease + 30
8   CoreFoundation                  0x362dc2e0 CFRelease + 88
9   APP_NAME_WAS_HERE                   0x000cea98 -[StoryViewController rewindToChunkIndex:] (StoryViewController.m:584)

過剰リリースのクラッシュ ログは次のようになります。

4

3 に答える 3

3

スタック トレースを見ると、クラッシュの原因は間違ったインデックスではなく、オブジェクトの過剰な解放です。

NSArray は、オブジェクトを追加すると保持メッセージを送信し、オブジェクトを削除すると解放メッセージを送信します。どうやら、そのリリースはクラッシュしています。

これは、配列に追加したオブジェクトを過剰に解放していることを意味します。

アップデート

あなたのサブビューは強く所有されていますか? あなたの所有権修飾子は「強い」ですか、それとも「弱い」ですか、それとも unsafe_unretained ですか? ARC であっても、変数を適切に「所有」していないと、不均衡な呼び出しが保持される可能性があります。たとえば、手動でビューを別の配列に追加および削除しているので、それを「所有」する必要があります。スーパービューから削除するとビューにリリースが送信され、addSubview は保持が送信されます。XIB を使用してビューを構築する場合、XIB 読み込みメカニズムはプロパティの所有権修飾子を使用し、それをビュー (StoryViewController.view) に追加するときにそれに応じて保持カウントを増やします。XIB ローディング メカニズムによってサブビューに追加されたため、アンロードしないでください。アンロードする場合は、サブビュー (アウトレット) のプロパティ タイプを「strong」に変更して「所有」する必要があります。

ARC 所有権修飾子を記述するときは、オブジェクト グラフと、誰が何を所有しているかという観点から考え始めます。ARC はガベージ コレクションとは異なります。このようなことはまだ起こります:)

于 2012-04-12T00:41:25.997 に答える
1

この問題に対する私の修正は、コンパイラの最適化レベルを、ターゲットのビルド設定のNone [-O0]デフォルト設定(リリースでのみ設定)から下げることでした。Fastest, Smallest [-Os]

それが単に問題を回避しているのか、それとも実際にコンパイラにバグがあるのか​​はわかりませんが、それで問題は解決します。そして、それはなぜテスターだけがそれを手に入れていたのかを説明しています。

于 2012-04-17T01:03:54.460 に答える
1

コードを見ずに、本当の問題が何であるかを言うのは難しいです。何かが過剰にリリースされているのは間違いないでしょう。ARCはCoreFoundationオブジェクトには適用されないことに注意してください。

allocwithと。の代わりに便利なコンストラクターを使用してプロパティを割り当てた可能性がありinitます。このようなオブジェクトは自動解放されるため、明示的に保持する必要があります。そうしないと、次のサイクルですぐに割り当てが解除されます。

于 2012-04-20T04:59:38.167 に答える