Is objc_msgSend() the significant piece that makes Objective-C object oriented? - objective-c

While reading the documentation, I wonder if objc_msgSend() is actually the "core technology" in delivering the functionality for making Objective-C "object oriented". Maybe someone can explain in more detail which other pieces come into place to enable the object oriented paradigm of Objective-C?

Not entirely.
Objective-C is object oriented solely because it encapsulates data and functionality into a single container; a class.
That is pretty much all there is to "object oriented programming".
Now, there are many different kinds of object oriented programming and one critical aspect is whether or not a language uses dynamic or static dispatch.
In a statically dispatched language -- C++ is the best example (yes, I know it has virtual methods that give a form of dynamic dispatch) -- a method call is wired up at compile time and cannot change at runtime. That is, the implementation of the method that will be used to fulfill the method call is fixed during compilation and cannot change at runtime.
With a dynamically dispatched language like Objective-C, the implementation of the method that will be used to fulfill a method call is determined each time the method call happens. Thus, through the use of categories or the runtime's API, it is possible to change a method's implementation while an application is running (this is actually how Key Value Observation works, for example).
objc_msgSend() is the hook that does the dynamic dispatch. It takes a reference to an object or a class & a method name -- a selector or SEL, as it is called -- and looks up the implementation on the object or class that goes by that method name. Once the implementation is found, it is called.
If no implementation is found, objc_msgSend() will then take a series of steps to see if the class or instance wants to handle the unrecognized method call somehow, allowing one object to stand in for another (proxying) or similar functionality.
There is a lot more to it than that. I would suggest you read Apple's documentation for more information.

There's quite a bit more to it.

Related

What's so special about message passing in smalltalk

I was going through an introduction to Smalltalk.
In C++, the functions declared inside a class can be called by objects of that class, and similarly in Smalltalk a keyword, termed as message, is written adjacent to the name of the object.
(Don't know much but would also like to ask here whether in response to a message a unique method is there to be executed?)
Basically, to my naive mind, this seems to be only a difference in syntax style. But, I wonder if internally in terms of compilation or memory structure this difference in calling holds any significance.
Thanks in advance.
P.S : I bow down to all of you for your time and answers . Thanks a lot.
The fundamental difference is that in Smalltalk, the receiver of the message has complete control over how that message is handled. It's a true object, not a data structure with functions that operate on it.
That means that in Smalltalk you can send any message to any object. The compiler places no restrictions on that, it's all handled at runtime. In C++, you can only invoke functions that the compiler knows about.
Also, Smalltalk messages are simply symbols (unique character strings), not a function address in memory as in C++. That means it's easy to send messages interactively, or over a network connection. There is a perform: method that lets you send a message given its string name.
An object even receives messages it does not implement. The Virtual Machine detects that case and creates a Message object, and then sends the messageNotUnderstood: message. Again, it's the object's sole responsibility of how to handle that unknown message. Most objects simply inherit the default implementation which raises an error, but an object can also handle it itself. It could, for example, forward those messages to a remote object, or log them to a file, etc.
You call a function in C++ because during the compilation time you know which function will be called (or at least you have a finite set of functions defined in a class hierarchy.
Smalltalk is dynamically typed and late bound, so during the compilation time you have no idea which method is going to be evaluated (if one will be at all). Thus you send a message, and if the object has a method with that selector, it is evaluated. Otherwise, the "message not understood" exception is raised.
There are already good answers here. Let me add some details (originally, part of this was in a comment).
In plain C, the target of each function call is determined at link time (except when you use function pointers). C++ adds virtual functions, for which the actual function that will be invoked by a call is determined at runtime (dynamic dispatch, late binding). Function pointers allow for custom dispatch mechanisms to some degree, but you have to program it yourself.
In Smalltalk, all message sends are dynamically dispatched. In C++ terms this roughly means: All member functions are virtual, and there are no standalone functions (there is always a receiver). Therefore, the Smalltalk compiler never* decides which method will be invoked by a message send. Instead, the invoked method is determined at runtime by the Virtual Machine that implements Smalltalk.
One way to implement virtual function dispatching is virtual function tables. An approximate equivalent in Smalltalk are method dictionaries. However, these dictionaries are mutable, unlike typical virtual function tables, which are generated by the C++ compiler and do not change at runtime. All Smalltalk behaviors (Behavior being a superclass of Class) have such a method dictionary. As #aka.nice pointed out in his answer, the method dictionaries can be queried. But methods can also be added (or removed) while the Smalltalk system runs. When the Smalltalk VM dispatches a message send, it searches the method dictionaries of the receiver's superclass chain for the correct method. There are usually caches in place to avoid the recurring cost of that lookup.
Also note that message passing is the only way for objects to communicate in Smalltalk. Two objects cannot access each other's instance variables, even if they belong to the same class. In C++, you can write code that breaks this encapsulation. Hence, message sending is fundamental in Smalltalk, whereas in C++ it is basically an optional feature.
In C++, Java, and similar languages, there is another form of dispatch, called function overloading. It happens exclusively at compile time and selects a function based on the declared types of the arguments at the call site. You cannot influence it at runtime. Smalltalk obviously does not provide this form of dispatch because it does not have static typing of variables. It can be realized nevertheless using idioms such as double dispatch. Other languages, such as Common Lisp's CLOS or Groovy, provide the even more general multiple dispatch, which means that a method will be selected based on both the receiver's type and the runtime types of all the arguments.
* Some special messages such as ifTrue: ifFalse: whileTrue: are usually compiled directly to conditional branches and jumps in the bytecode, instead of message sends. But in most cases it does not influence the semantics.
Here are a few example of what you would not find in C++
In Smalltalk, you create a new class by sending a message (either to the superclass, or to the namespace depending on the dialect).
In Smalltalk, you compile a new method by sending a message to a Compiler.
In Smalltalk, a Debugger is opened in response to an unhandled exception by sending a message. All the exception handling is implemented in term of sending messages.
In Smalltalk you can query the methods of a Class, or gather all its instances by sending messages.
More trivially, all control structures (branch, loops, ...) are performed by sending messages.
It's messages all the way down.

Do Objective-C objects get their own copies of instance methods?

I'm new to Objective-C and was wondering if anyone could provide any information to clarify this for me. My (possibly wrong) understanding of object instantiation in other languages is that the object will get it's own copies of instance variables as well as instance methods, but I'm noticing that all the literature I've read thus far about Objective-C seems to indicate that the object only gets copies of instance variables, and that even when calling an instance method, program control reverts back to the original method defined inside the class itself. For example, this page from Apple's developer site shows program flow diagrams that suggest this:
https://developer.apple.com/library/mac/documentation/cocoa/conceptual/ProgrammingWithObjectiveC/WorkingwithObjects/WorkingwithObjects.html#//apple_ref/doc/uid/TP40011210-CH4-SW1
Also in Kochan's "Programming in Objective-C", 6th ed., pg. 41, referring to an example fraction class and object, the author states that:
"The first message sends the setNumerator: message to myFraction...control is then sent to the setNumerator: method you defined for your Fraction class...Objective-C...knows that it's the method from this class to use because it knows that myFraction is an object from the Fraction class"
On pg. 42, he continues:
"When you allocate a new object...enough space is reserved in memory to store the object's data, which includes space for its instance variables, plus a little more..."
All of this would seem to indicate to me that there is only ever one copy of any method, the original method defined within the class, and when calling an instance method, Objective-C simply passes control to that original copy and temporarily "wires it" to the called object's instance variables. I know I may not be using the right terminology, but is this correct? It seems logical as creating multiple copies of the same methods would be a waste of memory, but this is causing me to rethink my entire understanding of object instantiation. Any input would be greatly appreciated! Thank you.
Your reasoning is correct. The instance methods are shared by all instances of a class. The reason is, as you suspect, that doing it the other way would be a massive waste of memory.
The temporary wiring you speak of is that each method has an additional hidden parameter passed to it: a pointer to the calling object. Since that gives the method access to the calling object, then it can easily access all of the necessary instance variables and all is well. Note that any static variable exists in only a single instance as well and if you are not aware of that, unexpected things can happen. However, regular local variables are not shared and are recreated for each call of a method.
Apple's documention on the topic is very good so have a look for more info.
Just think of a method as a set of instructions. There is no reason to have a copy of the same method for each object. I think you may be mistaken about other languages as well. Methods are associated with the class, not individual objects.
Yes, your thinking is more or less right (although it's simpler than that: behind the scenes in most such languages methods don't need to be "wired" to anything, they just take an extra parameter for self and insert struct lookups before references to instance variables).
What might be confusing you is that not all languages work this way, in their implementations and semantically. Object-oriented languages are (very roughly) divided into two camps: class-based, like Objective-C; and prototype-based, like Javascript. In the second camp of languages, a method or procedure really is an object in its own right and can often be assigned directly to an object's instance variables as well - there are no classes to lookup methods from, only objects and other objects, all with the same first-class status (this is an oversimplification, good languages still allow for sharing and efficiency).

How does an Objective-C method have access to the callee's ivars?

I was reading Apple's documentation, The Objective-C Programming Language (PDF link). On pg. 18, under The Receiver’s Instance Variables, I saw this.
A method has automatic access to the receiving object’s instance
variables. You don’t need to pass them to the method as parameters.
For example, the primaryColor method illustrated above takes no
parameters, yet it can find the primary color for otherRect and return
it. Every method assumes the receiver and its instance variables,
without having to declare them as parameters.
This convention simplifies Objective-C source code. It also supports
the way object-oriented programmers think about objects and messages.
Messages are sent to receivers much as letters are delivered to your
home. Message parameters bring information from the outside to the
receiver; they don’t need to bring the receiver to itself.
I am trying to better understand what they are describing; is this like Python's self parameter, or style?
Objective-C is a strict superset of C.
So Objective-C methods are "just" function pointers, and instances are "just" C structs.
A method has two hidden parameters. The first one is self(the current instance), the second _cmd (the method's selector).
But what the documentation is describing in page 18 is the access to the class instance variables from a method.
It just says a method of a class can access the instance variables of that class.
It's pretty basic from an object-oriented perspective, but not from a C perspective.
It also say that you can't access instance variables from another class instance, unless they are public.
While I would not say that it is a "slam" against Python, it is most certainly referring to the Python style of Object Orientation (which, in honesty, is derived from the "pseudo-object orientation" available in C (whether it is truly OO or not is a debate for another forum)).
It is good to remember that Python has a very different concept of scope from the rest of the world — each method more or less exists in its own little reality. This is contrasted with more "self-aware" languages which either have a "this" variable or an implicit instance construct of some form.

Objective-C Find all init (constructor methods)

using the "Method * class_copyMethodList(Class cls, unsigned int *outCount)" function one can get a list of all methods that exist on an objective-C class.
I would like to know how to find which of these methods are constructors as I am writing an IOC container. I would like to determine the constructors and their parameter types.
I would like to know how to find which of these methods are
constructors as I am writing an IOC container. I would like to
determine the constructors and their parameter types.
In short, you can't. Or, at the least, you'll find that down this path lies madness.
First, Objective-C does not have constructors. It has initializers, sometimes many, and -- for a properly written class -- only one of which is the designated initializer. There is no way to identify the designated initializer at compile time or run time.
How do I use this with a Method * and no instantiated member of the
class?
You don't. First you allocate an instance of the class, then you initialize the instance.
Overall, this level of abstraction just isn't done in Objective-C outside of academic investigations. It can be done, but it is generally avoided because of the fragility of the resulting solution and the hairball of code-hell that is trying to dynamically support the underlying C ABI (go look at the source to libffi).
If you want to go down this path, then you are far better off either defining a custom abstract class that all of your containers will subclass that can provide the binding logic to the class behind it.
Or use protocols; i.e. a class could implement an IOCBean protocol and one method would be initIOCGoop that is the designated initializer goo.
Doing this generically for all classes is going to be rife with fragility, special cases, and will require a gigantic mess of code that will be difficult to maintain over time.
You can get the method signature by using the following method:
methodSignatureForSelector:
From the documentation:
An NSMethodSignature object records type information for the arguments and return value of a method. It is used to forward messages that the receiving object does not respond to—most notably in the case of distributed objects. You typically create an NSMethodSignature object using NSObject’s methodSignatureForSelector: instance method (on Mac OS X v10.5 and later you can also use signatureWithObjCTypes:). It is then used to create an NSInvocation object, which is passed as the argument to a forwardInvocation: message to send the invocation on to whatever other object can handle the message. In the default case, NSObject invokes doesNotRecognizeSelector:, which raises an exception. For distributed objects, the NSInvocation object is encoded using the information in the NSMethodSignature object and sent to the real object represented by the receiver of the message.

Objective-C: my class with static methods "does not implement methodSignatureForSelector: -- trouble ahead"

I have a utility class which has only static methods, so it is not inheriting from NSObject (No need right?)
There are no warnings at all when compiling.
The problem comes when running on the iPhone simulator. It crashes with warning "does not implement methodSignatureForSelector: -- trouble ahead"
Well, I like that "trouble ahead" thing, I never heard a debugger telling me that there's "trouble ahead".
But what I don't like is the error itself... Why is it expecting me to implement methodSignatureForSelector in a class when I clearly call a static method? (+)
Thanks!
Daniel
This is not an idiomatic pattern in Cocoa. I would strongly recommend you rethink your design. This is not Java or C++. For one thing, there isn't even such a thing as a "static method" — they're class methods, with the class being an object itself.
It's also very weird to have a class that's not a subclass of NSObject ("no need" is not a very rational reason for deviating from the default behavior), and even weirder to have a class with only class methods. The class should probably either be a singleton or else eliminated and its methods turned into functions, depending on whether it needs to keep state.
As for the exact reason you're crashing, it's hard to say without seeing your code. That warning by itself should not crash your program. You do need to have some implementation of +initialize, even if it does nothing, because the runtime sends that message to every class that receives a message. That's probably where the error is coming up — you send a message, the runtime tries to send initialize, your class doesn't respond, the runtime tries to invoke the forwarding machinery and can't.
Thanks for the answer!
About the 'static' vs. 'class methods', AFAIK this is just naming, no real difference. Like 'functions/methods' and 'messages'.
However, this is not necessarily 'incorrect' design.
First you have to remember that ObjC has no namespacing, so the only way to put some order into things, is a class. Because if two functions' names collide, the compiler will shout loudly.
There ARE sometimes some functions that are 'Utility' functions and work on other objects, or do certain calculations, that can't be directly related to a certain object to manage them, and also they shouldn't, because that will just generate unnecessary overhead.
As a very experienced C/C++/Asm/Others prorgammer, when programming in ObjC, I tend to always release memory myself, for performance reasons.
For the same reasons, I wouldn't want to generate any overhead where its not needed. And ObjC has a lot of overhead.
The docs also do not say that I MUST inherit from NSObject, it says that I SHOULD when I want it to be correctly managed by the framework.
But as I understand it there's no need for any managing, these functions should be just functions wrapped inside a classname's namespace.
About +initiallize - that can only be overridden if the class inherits from NSObject. So the original question is still there - why should I inherit from NSObject if I do not want any of its services? I do not need to allocate the class or init it, as I have nothing to do with an instance of it!
Also a weird thing in ObjC is that you can override a class method?!