الحصول على استثناءات غريبة "محدد غير معترف بها" في تطبيق 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
هذا هو نظام التشغيل الذي يرسل تحذيرًا من الذاكرة إلى تطبيقي ، وقد تحولت فئة التطبيق بطريقة ما إلى سلسلة.
يبدو أن الأمر يحدث أكثر من ذلك بكثير عندما يتم استدعاء الكود عبر 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
الرمز المعني هو:
SECTURES SETOBJECT: FORKEY الملمس: اسم الملف] ؛
القوام عبارة عن نوع nsmutabledictionary* ولا يتم إعادة تعيينه أو إعادة تخصيصه أبدًا (بشكل طبيعي ، لأن هذا كائن ذاكرة التخزين المؤقت). هذا هو المكان الوحيد الذي يتم فيه استدعاء 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: identifier] ؛
كيف تحولت 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
نصائح أخرى
غالبًا ما يحدث هذا بسبب أخطاء إدارة الذاكرة. هل جربت الاموات الاحياء?
... مع تمكين الزومبي ، لن تتصرف الرسائل إلى الكائنات المعروضة بشكل غريب أو تعطل بطرق يصعب فهمها ، ولكنها ستقوم بدلاً من ذلك بتسجيل رسالة وتموت بطريقة يمكن التنبؤ بها وتصحيح الأخطاء. هذه هي الأداة التي يجب استخدامها عند محاولة تعقب الإفراط في الإفراج والإصدارات السابقة لأوانها.
لقد واجهت نفس المشكلة ، لكن اتضح أنني ارتكبت خطأً غبيًا:
لقد أعلنت عضوًا مثل هذا في ملف الرأس:
NSMutableDictionary* myDict;
ولكن بعد ذلك طورها هكذا في ملف .M:
myDict = [[NSDictionary alloc] init];
وهو أمر صالح وكل شيء ، لأن nsmutabletichary مستمدة من فئة NSDictionary. لذلك ، نجحت جميع المكالمات الموروثة من NSDictionary بالفعل ، ولكن المكالمات الخاصة بـ NSMutabledictionary [setObject: forkey:] فشلت لأنني حاولت استدعاءها في الفصل الأصل.
كان الخطأ غبيًا حقًا ، لكنني تم إلقاؤه أيضًا من خلال حقيقة أن مصحح الأخطاء أبلغ عن نوع mydict كشيء مختلف تمامًا (لا nsdictionary ، ولا nsmutabletichary). آمل أن يساعد هذا بعض المبرمج الآخر المتعب :-)