iPhoneアプリで奇妙な断続的な「認識されていないセレクター」例外を取得する
-
03-10-2019 - |
質問
最近、私はアプリから断続的なエラーレポートを受け取り、「認識されていないセレクター」を引き起こす可能性がありますが、それでもそうです。
たとえば、これ:
Error: NSInvalidArgumentException: *** -[NSCFString didReceiveMemoryWarning]: unrecognized selector sent to instance 0x541fe0
0 CoreFoundation 0x32de1e23 __handleUncaughtException + 230
1 libobjc.A.dylib 0x3266d894 _objc_terminate + 156
2 libstdc++.6.dylib 0x338c3a8c _ZN10__cxxabiv111__terminateEPFvvE + 84
3 libstdc++.6.dylib 0x338c3b04 _ZSt9terminatev + 24
4 libstdc++.6.dylib 0x338c3c2c __cxa_throw + 108
5 libobjc.A.dylib 0x3266be5c objc_exception_throw + 112
6 CoreFoundation 0x32de2bfd -[NSObject doesNotRecognizeSelector:] + 112
7 CoreFoundation 0x32d67b19 ___forwarding___ + 480
8 CoreFoundation 0x32d5e840 _CF_forwarding_prep_0 + 48
9 Foundation 0x33f765d9 _nsnote_callback + 184
10 CoreFoundation 0x32d9e511 _CFXNotificationPostNotification + 304
11 Foundation 0x33f741b3 -[NSNotificationCenter postNotificationName:object:userInfo:] + 70
12 Foundation 0x33f76519 -[NSNotificationCenter postNotificationName:object:] + 20
13 UIKit 0x30d18db8 -[UIApplication _performMemoryWarning] + 68
14 UIKit 0x30d18d50 -[UIApplication _receivedMemoryNotification] + 136
15 UIKit 0x30d18c80 _memoryStatusChanged + 64
16 CoreFoundation 0x32d66eb7 __CFNotificationCenterDarwinCallBack + 26
17 CoreFoundation 0x32d5cb51 __CFMachPortPerform + 78
18 CoreFoundation 0x32da452b CFRunLoopRunSpecific + 2302
19 CoreFoundation 0x32da3c1f CFRunLoopRunInMode + 50
20 GraphicsServices 0x31bb9374 GSEventRunModal + 196
21 UIKit 0x30bf3c30 -[UIApplication _run] + 560
22 UIKit 0x30bf2230 UIApplicationMain + 968
23 Mind 0x00002c68 main + 72
24 Mind 0x00002be4 start + 52
これは、私のアプリにメモリ警告を送信するOSであり、どういうわけかアプリケーションクラスが文字列に変更されました。
コードがnsoperationを介して呼び出されると、それはもっと多くのことが起こるようです。
Error: NSInvalidArgumentException: -[NSCFString setObject:forKey:]: unrecognized selector sent to instance 0x3e793088
9 Mind 0x0015de70 -[CCTextureCache textureFromFile:] + 528
10 Mind 0x0015d9f4 -[CCTextureCache loadImageUncached:pixelFormat:] + 116
11 Mind 0x0015d058 -[CCTextureCache addImage:pixelFormat:] + 152
12 Mind 0x00080524 -[ImageLoader imageWithFile:pixelFormat:] + 84
13 Mind 0x000854c4 -[ImageLoadOperation performLoad] + 68
14 Mind 0x00085800 -[ResourceLoadOperation main] + 112
15 Foundation 0x30c4c8b5 -[__NSOperationInternal start] + 664
16 Foundation 0x30c4c613 -[NSOperation start] + 22
17 Foundation 0x30cbdb63 ____startOperations_block_invoke_2 + 46
18 libSystem.B.dylib 0x31227858 _dispatch_call_block_and_release + 20
19 libSystem.B.dylib 0x3122863c _dispatch_worker_thread2 + 128
20 libSystem.B.dylib 0x311b1544 _pthread_wqthread + 400
21 libSystem.B.dylib 0x311a8b74 __stack_chk_fail + 4294967295
問題のコードは次のとおりです。
テクスチャSetObject:Texture ForKey:Filename];
テクスチャはタイプnsmutadedictionary*であり、再割り当てまたは扱いを受けることはありません(当然、これはキャッシュオブジェクトであるため)。これは、この方法でSetObjectが呼び出される唯一の場所ですが、スタックトレースによると、テクスチャは文字列でした。
私もこの奇妙さを得ます:
Error: NSInvalidArgumentException: -[NSConcreteNotification getPixelFormatForIdentifier:]: unrecognized selector sent to instance 0x5c021b0
9 Mind 0x0015dd0c -[CCTextureCache textureFromFile:] + 172
10 Mind 0x0015d9f4 -[CCTextureCache loadImageUncached:pixelFormat:] + 116
11 Mind 0x0015d058 -[CCTextureCache addImage:pixelFormat:] + 152
12 Mind 0x00080524 -[ImageLoader imageWithFile:pixelFormat:] + 84
13 Mind 0x000854c4 -[ImageLoadOperation performLoad] + 68
14 Mind 0x00085800 -[ResourceLoadOperation main] + 112
15 Foundation 0x347b78b5 -[__NSOperationInternal start] + 664
16 Foundation 0x347b7613 -[NSOperation start] + 22
17 Foundation 0x34828b63 ____startOperations_block_invoke_2 + 46
18 libSystem.B.dylib 0x32a2f858 _dispatch_call_block_and_release + 20
19 libSystem.B.dylib 0x32a3063c _dispatch_worker_thread2 + 128
20 libSystem.B.dylib 0x329b9544 _pthread_wqthread + 400
21 libSystem.B.dylib 0x329b0b74 __stack_chk_fail + 4294967295
このトレースは、cctexturecacheの次のコードからのものです。
cctexture2dpixelformat pixelformat = [self getpixelformatforidentifier:識別子];
cctexturecacheは、すでに多くの方法をそれ自体に呼び出した後、nsconcretenotificationにどのように変化したかは、控えめに言っても困惑しています。
他の誰かがこの種のことに気づいたことがありますか?私はどういうわけか記憶の腐敗を得ていますか?
解決
マルチスレッドに関するレース条件を確認しましたか?別のスレッドによって解放されたリソースのように思われ、現在のスレッドは、契約されたオブジェクトにメッセージを送信します。
Error: NSInvalidArgumentException: -[NSCFString setObject:forKey:]: unrecognized selector sent to instance 0x3e793088
9 Mind 0x0015de70 -[CCTextureCache textureFromFile:] + 528
10 Mind 0x0015d9f4 -[CCTextureCache loadImageUncached:pixelFormat:] + 116
11 Mind 0x0015d058 -[CCTextureCache addImage:pixelFormat:] + 152
12 Mind 0x00080524 -[ImageLoader imageWithFile:pixelFormat:] + 84
13 Mind 0x000854c4 -[ImageLoadOperation performLoad] + 68
14 Mind 0x00085800 -[ResourceLoadOperation main] + 112
15 Foundation 0x30c4c8b5 -[__NSOperationInternal start] + 664
16 Foundation 0x30c4c613 -[NSOperation start] + 22
17 Foundation 0x30cbdb63 ____startOperations_block_invoke_2 + 46
18 libSystem.B.dylib 0x31227858 _dispatch_call_block_and_release + 20
19 libSystem.B.dylib 0x3122863c _dispatch_worker_thread2 + 128
20 libSystem.B.dylib 0x311b1544 _pthread_wqthread + 400
21 libSystem.B.dylib 0x311a8b74 __stack_chk_fail + 4294967295
他のヒント
これは、多くの場合、メモリ管理エラーによって引き起こされます。試しましたか ゾンビ?
... Zombiesが有効になっていると、扱いにくいオブジェクトへのメッセージは、奇妙に動作したり、理解しにくい方法でクラッシュしたりしませんが、代わりにメッセージをログに記録し、予測可能でデバッガーのブレーク可能な方法で死にます。これは、過剰なリリースと早期リリースを追跡しようとするときに使用するツールです。
私は同じ問題に遭遇しましたが、愚かな間違いを犯したことがわかりました。
このようなメンバーをヘッダーファイルで宣言しました。
NSMutableDictionary* myDict;
しかし、そのように.mファイルで初期化しました:
myDict = [[NSDictionary alloc] init];
NSMUTABLEDICTIONARYはNSDictionaryクラスから派生しているため、これはすべて有効であり、すべてです。したがって、nsdictionaryから継承されたすべての呼び出しは実際には機能しましたが、nsmutabledictionary [setobject:forkey:]に固有の呼び出しは、親クラスでそれらを呼び出そうとしたために失敗しました。
間違いは本当に馬鹿げていましたが、デバッガーがMydictのタイプをまったく違うもの(nsdictionaryもNSMutadedictionaryも)として報告したという事実にも投げかけられました。これが他の疲れたコーダーに役立つことを願っています:-)