1

I have this error going on in 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.

Hoodai
  • 105
  • 1
  • 3
  • 14
  • 4
    Can you find the line where the exception is being thrown? Try setting an Exception breakpoint - go to the Breakpoints list and press the + at the bottom. – architectpianist Jun 27 '13 at 18:10
  • First off, scan your app for "decompressing" in a selector or property name -- somewhere a string is being passed instead of the appropriate object. Then set the exception breakpoint as described above and/or [add an exception traceback to your `main`](http://stackoverflow.com/a/12268397/581994). – Hot Licks Jun 27 '13 at 18:36
  • @architectpianist using the exceptions breakpoint allowed me to narrow down the search and find where the problem was. This lead me to a solution. My problem was I was saving a NSString (a filename) as a UIImage. I had forget the part of the line "[UIImage imageWithContentsOfFile:NSString]" to load the image out of the file. – Hoodai Jun 28 '13 at 18:17

4 Answers4

4

When you have unrecognized selector send to instance error, 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 NSString most of the time the class is wrong.

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

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

danypata
  • 9,895
  • 1
  • 31
  • 44
  • Best answer b/c of last line "A good way to find the line that is causing the crash is to enable exceptions breackpoints." Real solution in comments of question – Hoodai Jun 28 '13 at 18:18
1

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?

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).

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 instance exception.

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 selector exception, since the class which the object belongs to is part of the object structure - the isa pointer. 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.

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.

Community
  • 1
  • 1
Charlie Monroe
  • 1,210
  • 9
  • 24
  • When you call a method on a deallocated object you get `message sent to deallocated instance` not `unrecognized selector`. And did you know of a NSString mehtod called `_isDecompressing` ? :)) – danypata Jun 27 '13 at 18:25
  • That is not entirely true. This depends on various things - if the underlying allocator (usually malloc) already returns the page where the object was to the kernel, then the app will crash with no log (EXC_BAD_ACCESS). If you simply release the object and it is deallocated, another message sent to that object will cause the `message sent to deallocated instance`. However, if the memory that your initial object occupied was taken by another object, 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 selector` exception. – Charlie Monroe Jun 30 '13 at 08:07
0

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.

Brad
  • 486
  • 2
  • 8
0

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.

(Ask me how I know!)

savinola
  • 380
  • 4
  • 6