xcode 'NSInvalidArgumentException',原因:'-[__NSCFString _isDecompressing]:无法识别的选择器

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17350280/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 03:32:58  来源:igfitidea点击:

'NSInvalidArgumentException', reason: '-[__NSCFString _isDecompressing]: unrecognized selector

iosxcode

提问by Hoodai

I have this error going on in Xcode:

我在 Xcode 中发生此错误:

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFString _isDecompressing]: unrecognized selector sent to instance 0x71863b0'

I have quite a bit of code and classes so I don't know what would need to be posted to start looking at this issue. If someone could give me some direction on how to start fixing this, it would be much appreciated. p.s. if there is anything else that needs to be posted tell me and I'll edit.

我有很多代码和类,所以我不知道需要发布什么才能开始研究这个问题。如果有人能给我一些关于如何开始解决这个问题的指导,我将不胜感激。ps如果还有什么需要发布的告诉我,我会编辑。

回答by danypata

When you have unrecognized selector send to instanceerror, you have to check if you declared and implemented the method that is pointed out by the error, in your case _isDecompressing. If everything is ok on your class (the method is declared and implemented) then have a look at the class type that is calling the method, in your case NSStringmost of the time the class is wrong.

当你有unrecognized selector send to instance错误时,你必须检查你是否声明并实现了错误指出的方法,在你的情况下_isDecompressing。如果您的类上一切正常(该方法已声明并实现),那么请查看调用该方法的类类型,在您的情况下,NSString大多数情况下该类是错误的。

So in order to point out your problem, you are trying to call a method _isDecompressingon NSStringwhich doesn't exist. So make sure every object that calls this method is of your desired type and not NSString

因此,为了指出你的问题,你想调用一个方法_isDecompressingNSString不存在。因此,请确保调用此方法的每个对象都是您想要的类型,而不是NSString

A good way to find the line that is causing the crash is to enable exceptions breackpoints.

找到导致崩溃的行的一个好方法是启用异常断点。

回答by Charlie Monroe

The most likely cause of this crash is that you are sending a message to a deallocated instance of an object - try running your app with NSZomie's enabled - see e.g. How do I set up NSZombieEnabled in Xcode 4?

导致此崩溃的最可能原因是您正在向对象的释放实例发送消息 - 尝试在启用 NSZomie 的情况下运行您的应用程序 - 参见例如如何在 Xcode 4 中设置 NSZombieEnabled?

What is going on is that the memory used by your object gets marked as unused when deallocated and some other object gets allocated in that place. This object, however, is of a different class, hence the does not recognize selector message.

正在发生的事情是,您的对象使用的内存在释放时被标记为未使用,并且在该位置分配了其他一些对象。然而,这个对象属于不同的类,因此它不能识别选择器消息。

As noted in the comments, the way sending messages to deallocated instances manifests itself varies:

正如评论中所指出的,向释放的实例发送消息的方式本身就各不相同:

The object is allocated somewhere in memory - on a page, which is split into parts by an allocator - e.g. malloc. If the underlying allocator already returned the page where the object was to the kernel, then the app will crash with no log (EXC_BAD_ACCESS).

该对象被分配在内存中的某处——在一个页面上,它被一个分配器分成几部分——例如 malloc。如果底层分配器已经将对象所在的页面返回给内核,那么应用程序将崩溃并且没有日志 (EXC_BAD_ACCESS)。

If the object was released and the retain count reached 0 it was deallocated, meaning just marking the memory on the page as free for future use. If you hence try to send another message to that object, the runtime will notice that the object has no retain count, hence was deallocated and will case the message sent to deallocated instanceexception.

如果对象被释放并且保留计数达到 0,它就会被释放,这意味着只是将页面上的内存标记为空闲以备将来使用。如果您因此尝试向该对象发送另一条消息,运行时将注意到该对象没有保留计数,因此已被释放并会引发message sent to deallocated instance异常。

If, however, the memory that your initial object occupied was taken by another object in between, there's no way for the runtime to know that there was once an object you intend to call a method on, hence the unrecognized selectorexception, since the class which the object belongs to is part of the object structure - the isapointer. Nothing else is (or can be) checked by the run-time. For the runtime, it's a valid request to send a message to an object, however, there's no such method on the new object.

但是,如果您的初始对象占用的内存被介于两者之间的另一个对象占用,则运行时无法知道曾经有一个您打算对其调用方法的对象,因此出现unrecognized selector异常,因为对象所属是对象结构的一部分——isa指针。运行时不会(或不能)检查其他任何内容。对于运行时,向对象发送消息是有效的请求,但是,新对象上没有这样的方法。

This can be potentially dangerous if the new object responds to the same message which does something lethal in one class, since the method is actually called on the object if it is a valid method name!

如果新对象响应在一个类中执行某些致命操作的相同消息,则这可能具有潜在危险,因为如果对象是有效的方法名称,则该方法实际上是在对象上调用的!

Of course, there are other scenarios, e.g. the object will overwritten by other data, hence the isa pointer points to a non-existant class and a crash will occur just as in the first place, since the OS will try to dereference an address that is not valid in the context of your process.

当然,还有其他情况,例如对象将被其他数据覆盖,因此 isa 指针指向一个不存在的类,并且会像最初一样发生崩溃,因为操作系统将尝试取消引用一个地址在您的流程上下文中无效。

回答by Brad

In the debugger console, use 'bt' to get a backtrace, then disassemble the first address in the backtrace the is noticeably smaller than the other values... the small valued addresses are your code.

在调试器控制台中,使用“bt”获取回溯,然后反汇编回溯中的第一个地址,该地址明显小于其他值……小值地址是您的代码。

回答by savinola

This is easy to hit if you pull an image name out of, say, a JSON dictionary and pass it straight into something that expects a UIImage; since the values aren't type checked, the compiler will miss the error and you'll get a runtime crash.

如果您从 JSON 字典中提取图像名称并将其直接传递给需要UIImage; 由于这些值没有经过类型检查,编译器将错过错误并且您将遇到运行时崩溃。

(Ask me how I know!)

(问我怎么知道的!)