0

I'm reading this programming book with the following code

#import "Fraction.h"
int main (int argc, char * argv [])
{
    @autoreleasepool {
        Fraction *f = [[Fraction alloc] init];
        [f noSuchMethod];
        NSLog (@"Execution continues!");
    }
    return 0;
}

Apparently it's supposed to give me the following output:

* Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[Fraction noSuchMethod]: unrecognized selector sent to instance 0x103f00' * Call stack at first throw:'')

Instead I just get an error that says: No visible @interface for 'Fraction' declares the selector 'noSuchMethod'

Is this because I have a newer version of xcode, or am I doing something wrong? It seems pretty straight forward to me.

Edit:

Also... Would this following code work in the newest version of xcode?

int main (int argc, char * argv [])
{
    @autoreleasepool {
        Fraction *f = [[Fraction alloc] init];
        @try {
            [f noSuchMethod];
        }
        @catch (NSException *exception) {
            NSLog(@"Caught %@%@", [exception name], [exception reason]);
        }
        NSLog (@"Execution continues!");
    }
return 0;
}

Edit #2: enter image description here

RCYup
  • 61
  • 1
  • 4
  • possible duplicate of [Why is 'no known method for selector x' a hard error under ARC?](http://stackoverflow.com/questions/9245317/why-is-no-known-method-for-selector-x-a-hard-error-under-arc) – trojanfoe Dec 07 '12 at 12:05

1 Answers1

2

Xcode doesn't let you compile if you call a method that certainly doesn't exist.

Else use the performSelector: method.

EDIT

If you directly call the method it won't compile, like in the initial question you have asked.

If you still want to call this method for some reason, because maybe it's private or something else, you can call it via performSelector:.

It will still tell you that the object might not respond to it. You can suppress the warning, as you can see here:

http://www.stackoverflow.com/a/7933931/1320374

IluTov
  • 6,807
  • 6
  • 41
  • 103
  • 3
    The book probably refers to an earlier version of Xcode. The version used in the book apparently was not checking for method existence at compile time and therefore threw a runtime exception. The version of Xcode you are now using checks for the existence of a method in question at compile time. – FluffulousChimp Dec 07 '12 at 10:35
  • Thanks for your quick response. Might you be able to give me some more input on my most recent edit to the question? Thanks! – RCYup Dec 07 '12 at 10:47
  • "Doesn't let you compile?" It just generates a warning but it certainly compiles. – trojanfoe Dec 07 '12 at 10:49
  • @RCYup Not because of the missing method, but rather the missing class! – trojanfoe Dec 07 '12 at 10:52
  • @trojanfoe I have the class defined. It's giving me an error. Even if I change it to id, it still gives me the same error. – RCYup Dec 07 '12 at 10:55
  • @RCYup I don't see the class defined in the code you posted. EDIT: it's obviously in `Fraction.h` doh. However I don't understand this. I have come across this many times in my own code and the compiler generates the warning "class X may not respond to selector Y", but it does compile it anyway. – trojanfoe Dec 07 '12 at 10:58
  • @trojanfoe I didn't include the #import "Fraction.h" in my example but it's there in my code. – RCYup Dec 07 '12 at 11:00
  • 1
    No, like i wrote in my answer. You can call performSelector: on the Fraction object. Then it will compile and you'll get an exception – IluTov Dec 07 '12 at 11:04
  • So what's the difference between the warning "class may not respond to selector" and the error "no known instance method for selector"? Is it the selector is defined in a different class so the compiler knows there is a selector of that name (which in this case there isn't)? – trojanfoe Dec 07 '12 at 11:07
  • @trojanfoe If you directly call the method it won't compile, like in the initial question you have asked, though if you still want to call this method for some reason, because maybe it's private or something else, you can call it via `performSelector:`. It will still tell you that the object might not respond to it. You can suppress the warning, as you can see here: http://stackoverflow.com/a/7933931/1320374 – IluTov Dec 07 '12 at 11:15
  • @RCYup The compiler aborts the compilation as soon as it gets any errors, this is what we call "not compiling". – IluTov Dec 07 '12 at 11:16
  • Oh, this only happens when using ARC? That would explain a lot! – trojanfoe Dec 07 '12 at 11:25
  • @trojanfoe Why ARC? This doesn't have to do anything with ARC – IluTov Dec 07 '12 at 11:33
  • @NSAddict Are you sure? As I have mentioned, in my code (MRR), mistakes like this only generate a warning in Xcode. – trojanfoe Dec 07 '12 at 11:37
  • @trojanfoe ARC simply inserts `retain` and `release` calls for you. When do you only get a warning? – IluTov Dec 07 '12 at 11:39
  • @NSAddict Well I am not certain (I would have to create 2 sample projects to know for sure and I am not near my Mac), however the SO question you linked to had the accepted answer with "My guess about this is this: since the selector is unknown to the compiler, ARC cannot enforce proper memory management", which got me thinking that was the difference in behaviour. – trojanfoe Dec 07 '12 at 11:42
  • @trojanfoe It's actually about the `LLVM 3.0 compiler in Xcode 4.2`, not ARC – IluTov Dec 07 '12 at 11:53
  • @NSAddict http://stackoverflow.com/questions/9245317/why-is-no-known-method-for-selector-x-a-hard-error-under-arc – trojanfoe Dec 07 '12 at 11:57
  • @trojanfoe Oh, didn't know that. Sorry, my bad. So that post you just mentioned explains it.. – IluTov Dec 07 '12 at 12:02