3

最近,我从我的应用程序中收到间歇性错误报告,声称在不可能导致它们的区域出现“无法识别的选择器”,但它们确实如此。

例如,这个:

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

有问题的代码是:

[纹理 setObject:texture forKey:filename];

textures 是 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 是令人费解的。

有没有其他人注意到这种事情?我是否以某种方式获得内存损坏?

4

3 回答 3

1

您是否检查了有关多线程的一些竞争条件?似乎另一个线程释放了一些资源,并且当前线程向释放的对象发送了消息。

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
于 2010-09-17T22:18:21.210 回答
0

这通常是由内存管理错误引起的。你试过僵尸吗?

...启用僵尸后,已释放对象的消息将不再表现异常或以难以理解的方式崩溃,而是会记录一条消息并以可预测和调试器断点的方式死亡。这是在尝试追踪过度发布和过早发布时使用的工具。

于 2010-09-17T20:19:50.927 回答
0

我刚刚遇到了同样的问题,但事实证明我犯了一个愚蠢的错误:

我在头文件中声明了一个这样的成员:

NSMutableDictionary* myDict; 

但随后在 .m 文件中像这样初始化它:

myDict = [[NSDictionary alloc] init];

这是有效的,因为 NSMutableDictionary 派生自 NSDictionary 类。因此,从 NSDictionary 继承的所有调用实际上都有效,但是特定于 NSMutableDictionary [setObject: forKey:] 的调用失败了,因为我试图在父类上调用它们。

这个错误真的很愚蠢,但我也被调试器报告 myDict 的类型完全不同(既不是 NSDictionary 也不是 NSMutableDictionary)这一事实所抛弃。我希望这可以帮助其他一些疲惫的编码员:-)

于 2011-03-22T06:20:21.610 回答