私のアプリはコアデータを使用しています。最近Xcode 10.2にアップグレードし、Swift 5になりました。それ以降、コアデータに関連するランダムなクラッシュが発生しています。
私が収集したものから、これはバックグラウンドスレッドからコアデータを変更しようとしたときに発生しました(サーバーから新しいデータをプルした後)。
次のエラーメッセージが表示される
2019-03-31 14:49:17.358685+0300 LeaderMES[24226:595701] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSTaggedDate objectForKey:]: unrecognized selector sent to instance 0x8000000000000000'
または
2019-03-31 14:37:04.676485+0300 LeaderMES[23749:583097] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[_NSCoreDataTaggedObjectID objectForKey:]: unrecognized selector sent to instance 0x8000000000000000'
以前使用していたコードだけでなく、このインスタンス番号は疑わしく見えます
私のアプリは、これらのエラーの1つをキャッチしたcrashlyticsに接続されています。キャッチしたスタックトレースは次のとおりです。
Fatal Exception: NSInvalidArgumentException
0 CoreFoundation 0x1086f86e3 (Missing)
1 libobjc.A.dylib 0x10771bac5 objc_exception_throw
2 CoreFoundation 0x108716ab4 (Missing)
3 CoreFoundation 0x1086fd443 (Missing)
4 CoreFoundation 0x1086ff238 (Missing)
5 libswiftCore.dylib 0x109914dcc (Missing)
6 libswiftCore.dylib 0x109b407b9 (Missing)
7 LeaderMES 0x105080a8d closure #1 in LMNotificationRepository.loadNotificationHistory(forFactory:successCompletion:errorCompletion:) (LMNotificationRepository.Swift:360)
8 LeaderMES 0x105091271 partial apply for closure #1 in LMNotificationRepository.loadNotificationHistory(forFactory:successCompletion:errorCompletion:) (<compiler-generated>)
9 LeaderMES 0x10510b872 closure #1 in LMHttpProvider.procedeRequest(_:completionHandler:) (LMHTTPProvider.Swift:299)
10 LeaderMES 0x10510e381 partial apply for closure #1 in LMHttpProvider.procedeRequest(_:completionHandler:) (<compiler-generated>)
11 LeaderMES 0x1050ce176 thunk for @escaping @callee_guaranteed (@guaranteed Data?, @guaranteed NSURLResponse?, @guaranteed Error?) -> () (<compiler-generated>)
12 CFNetwork 0x10adf6178 (Missing)
13 CFNetwork 0x10ae0cc56 (Missing)
14 Foundation 0x10666f412 __NSBLOCKOPERATION_IS_CALLING_OUT_TO_A_BLOCK__
15 Foundation 0x10666f31a -[NSBlockOperation main]
16 Foundation 0x10666c1f4 -[__NSOperationInternal _start:]
17 Foundation 0x106671f5b __NSOQSchedule_f
18 libdispatch.dylib 0x10a539ccf (Missing)
19 libdispatch.dylib 0x10a53ad02 (Missing)
20 libdispatch.dylib 0x10a53d6be (Missing)
21 libdispatch.dylib 0x10a53cd49 (Missing)
22 libdispatch.dylib 0x10a549ad3 (Missing)
23 libdispatch.dylib 0x10a54a330 (Missing)
24 libsystem_pthread.dylib 0x10a91c6b3 (Missing)
25 libsystem_pthread.dylib 0x10a91c3fd (Missing)
不足しているすべてのdylibは何ですか?
運が悪いDispatchQueueを使用して、すべてのコアデータアクティビティをメインスレッドに移動しようとしました。
アプリをシミュレーターから削除して再インストールしましたが、今のところクラッシュは繰り返されません。このクラッシュの原因について何か考えはありますか?
Xcode 10.2で行われた非最適化ビルドのバグのようです。アプリでCore Dataを使用していませんが、それもクラッシュします
-[xxx objectForKey:]: unrecognized selector sent to instance 0x8000000000000000'
XXXは__NSTaggedDate
の場合もあれば、別のタイプの場合もありますが、アドレスは常に0x8000000000000000
です。有効なキーで有効な辞書にアクセスするとデバッガーが行で停止し、まったく役に立ちません。デバッグスキームの最適化をOptimise for speed -O
に変更すると、アプリがクラッシュしなくなります。
通常、辞書に使用されるメソッドobjectForKey:を送信しています。ただし、レシーバーはTaggedDateオブジェクトです。 TaggedDateは基本的にNSDateと同じです(ここでの目的)。したがって、どういうわけか、辞書を期待する場所にNSDateオブジェクトを持つことができました。
例外にブレークポイントを追加すると、呼び出し元に戻って、辞書を期待していた場所にNSDateオブジェクトがある理由がわかります。 dictがNSDateであることが判明した場合は、dict [@ "some key"]のような行が期待されます。
同様の問題が、2つの異なるスレッド(コードの2つの異なる場所)からオブジェクトに同時にアクセスしてアクセスしているときに発生しました。アドレスが変更されているはずです。 DispatchQueueを使用してこのオブジェクトへのアクセスを同期することで解決しました
var lock:DispatchQueue = DispatchQueue.init(label: "")
lock.sync {アクセスオブジェクト}