Objective-C Messages

Discussion in 'Mac Programming' started by yippy123, Dec 23, 2008.

  1. yippy123 macrumors newbie

    Joined:
    Dec 23, 2008
    #1
    Hi Everyone,

    I'm fairly new to Objective-C and I come from a C and Java background. I just had a question about messages. I know it's similar to calling a function/method but the object may choose to ignore it or forward the message. Ok, I got that.

    So I did some playing around just to learn ObjC and I'm getting confused a message call.

    I had two classes, Test1 and Test2. Both implement an "add" function.

    Test1's add takes in a Test1 object as an argument. This is similar to Test2.

    Here is the code:
    Test1 test1 = [[Test alloc] init];
    Test2 test2 = [[Test2 alloc] init];

    id value1 = test1;
    id value2 = test2;
    id value3 = nil;

    value3 = [value1 add: value2];

    My confusion is that even though it compiles, I don't get a runtime error. It executes just fine even tho the argument for Test1's add requires a Test1 object, yet if you see here, I'm passing in a Test2 object. Shouldn't the compiler look up the "add" method/function from value1 (which is a Test1 object)?

    How come there is no runtime error? I know it has something to do with dynamically typed variables, but Test1's add function requires a Test1 object. So, when a message is sent, it goes to a selector and calls the appropriate function regardless of the argument types??

    Coming from a statically typed background, this kinda confuses me. Could someone explain? Hopefully, my question is easily understandable. If not, please let me know.

    Many thanks.
     
  2. Catfish_Man macrumors 68030

    Catfish_Man

    Joined:
    Sep 13, 2001
    Location:
    Portland, OR
    #2
    You're passing an id (a typedef of struct objc_object), so it really has no idea whether you're passing the right kind of object. I suspect if you check your compiler warnings (not errors) you'll find it complaining about this uncertainty. The underlying C function (objc_msgSend) is declared as id objc_msgSend(id, SEL, ...), so all your arguments are ending up in the varargs at the end.

    As for runtime errors, it sounds like your add method doesn't actually do anything Test2 doesn't support. If it did you'd get exceptions thrown when it didn't respond to the messages you passed it.
     
  3. gnasher729 macrumors P6

    gnasher729

    Joined:
    Nov 25, 2005
    #3
    Objective-C methods are dynamic. In your example, the compiler knows that you are sending a method named "add:". It doesn't matter that it doesn't know the type of the object; it will examine which methods the object understands at runtime, and either call the right method, or it will call a specific method that handles all calls to methods that can't be found.

    When the type known to the compiler is "id", it doesn't know what methods the object understands at compile time. Giving a compiler warning would be pointless because you could never send a method to an "id" without a warning. If the object pointer has a propert type (like NSString*) instead of just "id", the compiler knows which methods the object understands and can check that your method is one of those. It is possible to hide some of the methods that a class understands from the compiler; if you use one of those, you will get a warning, but the methd call will still work.

    You should also learn what a "protocol" is; a protocol tells the compiler not what kind of object you've got, but some of the methods it understands.
     
  4. Krevnik macrumors 68030

    Krevnik

    Joined:
    Sep 8, 2003
    #4
    As a second comment on the protocol thing, another way to look at protocols is that they are synonymous to Java's interfaces. They represent the same ideas.
     

Share This Page