質問

これは本当に奇妙です...

私はアプリを実行していますが、それが開いている間、ビューが構築されている間、私は取得します:

Collection <CALayerArray: 0x124650> was mutated while being enumerated.

コードトレースは次のとおりです。

main
UIApplicationMain
-[UIApplication _run]
CFRunLoopRunInMode
CFRunLoopRunSpecific
_UIApplicationHandleEvent
-[UIApplication sendEvent:]
-[UIApplication handleEvent:withNewEvent:]
-[UIApplication _runWithURL:sourceBundleID:]
-[UIApplication _performInitilizationWithURL:sourceBundleID:]
-[AppDelegate applicationDidFinishLaunching:]
+[Controller initializeController] //This is my own function
    [window addSubview: pauseMenuController.view] //This is the last point of my code it goes through
-[UIView(Hierarchy) addSubview:]
-[UIView(Internal) _addSubview:positioned:relativeTo:]
-[UIView(Hierarchy) _makeSubtreePerformSelector:withObject:]
-[UIView(Hierarchy) _makeSubtreePerformSelector:withObject:withObject:copySublayers:]
-[UIView(Hierarchy) _makeSubtreePerformSelector:withObject:withObject:copySublayers:]
_NSFastEnumerationMutationHandler
objc_exception_throw

私は何度もゲームをたくさん実行してきましたが、これを見たことがありませんでした。奇妙なことは、私が他のスレッド(私が知っている)を作成していないということです このコードはすべて呼び出されます。誰かがUiviewでアクセスしている間に変更されている可能性のあるものについて誰かが私に説明をすることができれば、これをデバッグする方が簡単です。それはすでに何かを追加している間に、ビューに何かを追加することと関係がありますか?何か案は?

役に立ちましたか?

解決

並行性の例外ではありません。列挙変異の例外は、何か(おそらく同じスレッド内のループ内)がループが反復しているアレイ/セット/辞書を変更すると発生します。

AddSubview:はスタックにあるので、私の推測では、建設中にUiViewのサブビューの1つを削除しようとしていると思います。

実行される可能性のある方法をオーバーライドしていますか? addsubviewまたは場合によってはレイアウトサブビューが好きですか?これらのいずれかがサブビューを削除している場合、これにより問題が発生します。

他のヒント

あなたの見解には、あなたが代表者を見解に割り当てたサブレイヤーがいる可能性はありますか?これにより、通常、ビューが無限に反発します(まあ、スタック制限に達するまで)呼び出すときに _makeSubtreePerformSelector:withObject:withObject:copySublayers:, 、しかし、ここでやろうとしていることは何でも突然変異を伴う可能性があると思います。

これがそうである理由は、UiviewがCalayerの代表者がUiviewである場合、CalayerがUiviewに属し、Uiviewが階層の一部であると想定しているためです。ただし、独自のカレイヤーを作成し、デリゲートをUiviewに割り当てると、Uiviewは再帰の一部として自分自身を呼び出すことになります。

ドキュメントから:

列挙は「安全」です。列挙者には突然変異ガードがあるため、列挙中にコレクションを変更しようとすると、例外が提起されます。

基本的に、これは、Objective-C 2.0で導入された高速列挙を使用して列挙している間に、コレクション(たとえば配列など)にオブジェクトを追加/削除することが許可されていないことを意味します。そうすることで、突然変異ガードが無効になるからです。

あなたの場合、コレクションはビュー階層に関連しています。この特定のコレクションにビューを追加および/または削除する場合は、高速列挙を使用しないでください。

Calayerの-DealLocメソッド中にプロパティをクリアしようとすると、これがカレイヤーズ内で起こるのを見てきましたが、そのプロパティを変更するだけで、レイヤーの可視性を変えるだけです。同じビューの-dealloc中に、あなたがあなたのビューの1つのプロパティを変更する何かを何らかの形で行っているかどうかを確認して確認できます。

私は同じバグにぶつかりました。私は、メイン以外のスレッドのビュー階層を変異させていました。ビューのすべての変更がメインスレッドで実行されていることを確認してください。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top