C function vs. Objective-C method? - objective-c

What is the difference between the two? If I'm writing a program, when would I need a this:
void aFunction() {
//do something
}
and when would I need this:
-(void)aMethod {
//do something else
}

Actually, an Objective-C method is just a C function with two arguments always present at the beginning.
This:
-(void)aMethod;
Is exactly equivalent to this:
void function(id self, SEL _cmd);
Objective-C's messaging is such that this:
[someObject aMethod];
Is exactly equivalent to this (almost -- there is a variadic argument ABI issue beyond the scope of this answer):
objc_msgSend(someObject, #selector(aMethod));
objc_msgSend() finds the appropriate implementation of the method (by looking it up on someObject) and then, through the magic of a tail call optimization, jumps to the implementation of the method which, for all intents and purposes, works exactly like a C function call that looks like this:
function(someObject, #selector(aMethod));
Quite literally, Objective-C was originally implemented as nothing but a C preprocessor. Anything you can do in Objective-C could be rewritten as straight C.
Doing so, however, would be a complete pain in the ass and not worth your time beyond the incredibly educational experience of doing so.
In general, you use Objective-C methods when talking to objects and function when working with straight C goop. Given that pretty much all of Mac OS X and iOS provide Objective-C APIs -- certainly entirely so for the UI level programming entry points -- then you use Obj-C most of the time.
Even when writing your own model level code that is relatively standalone, you'll typically use Objective-C simply because it provides a very natural glue between state/data & functionality, a fundamental tenant of object oriented programming.

In Objective-C each function operates on an object, like
[myObject myFunction]
A C method has the form:
return-type function-name(argument1, argument2, etc) {}
An Objective-C instance method has the form:
-(return-type)function-name:argument1 {}
or for a multi-argument function
-(return-type)function-name:argument1 function-name:argument2 {}
I always use Objective-C-style methods in Obj-C programming, even though you can still use C-type functions as well.
I suppose the equivalent in C to [myObject myMethod:arg] might be myObject.myMethod(arg)

The first is a freestanding function. The second is an instance method for an Objective-C class. So I guess you would need the second version if you're actually writing a class.

Related

Can Foundation tell me whether an Objective-C method requires a special structure return?

Background as I understand it: Objective-C method invocations are basically a C function call with two hidden parameters (the receiver and the selector). The Objective-C runtime contains a function named objc_msgSend() that allows to invoke methods that way. Unfortunately, when a function returns a struct some special treatment may be needed. There are arcane (some might say insane) rules that govern whether the structure is returned like other values or whether it's actually returned by reference in a hidden first argument. For Objective-C there's another function called objc_msgSend_stret() that must be used in these cases.
The question: Given a method, can NSMethodSignature or something else tell me whether I have to use objc_msgSend() or objc_msgSend_stret()? So far we have found out that NSMethodSignature knows this, it prints it in its debug output, but there doesn't seem to be a public API.
In case you want to respond with "why on earth would you want to do that?!", please read the following before you do: https://github.com/erikdoe/ocmock/pull/41
Objective-C uses the same underlying ABI for C on a given architecture, because methods are just C functions with implicit self and _cmd arguments.
In other words, if you have a method:
- (SomeStructType)myMeth:(SomeArgType)arg;
then really this is a plain C function:
SomeStructType myMeth(id self, SEL _cmd, SomeArgType arg);
I'm pretty sure you already know that, but I'm merely mentioning it for other readers.
In other words, you want to ask libffi or any kind of similar library how SomeStructType would be returned for that architecture.
NSMethodSignature has a -methodReturnType that you can inspect to see if the return type is a struct. Is this what you're trying to do?
From http://www.sealiesoftware.com/blog/archive/2008/10/30/objc_explain_objc_msgSend_stret.html:
The rules for which struct types return in registers are always
arcane, sometimes insane. ppc32 is trivial: structs never return in
registers. i386 is straightforward: structs with sizeof exactly equal
to 1, 2, 4, or 8 return in registers. x86_64 is more complicated,
including rules for returning floating-point struct fields in FPU
registers, and ppc64's rules and exceptions will make your head spin.
The gory details are documented in the Mac OS X ABI Guide, though as
usual if the documentation and the compiler disagree then the
documentation is wrong.
If you're calling objc_msgSend directly and need to know whether to
use objc_msgSend_stret for a particular struct type, I recommend the
empirical approach: write a line of code that calls your method,
compile it on each architecture you care about, and look at the
assembly code to see which dispatch function the compiler uses.

Why does method_getNumberOfArguments return two more results than the selector would imply?

In the objective-C runtime, why does method_getNumberOfArguments return two more results than the selector would imply?
For example, why does #selector(initWithPrice:color:) return 4?
TL;DR
Alright. Just to set the record straight, yes, the first two arguments to any objective-c method are self and _cmd, always in that order.
A brief history of Objective-C
However, the more interesting subject is the why to this scenario. To do that, we must first look into the history of objc. Without further ado, let's get started.
Way back in 1983, Brad Cox, the 'God' of objective-c, wanted to create an object-oriented runtime-based language on top of C, for good performance and flexibility across platforms. As a result, the very first Objective-C 'compilers' were just simple preprocessors of Objective-C source converted to their C-runtime equivalents, and then compiled with the platform specific C compiler tool.
However, C was not designed for objects, and that was the most fundamental thing that Objective-C had to surmount. While C is a robust and flexible language, runtime support is one of it's critical downfalls.
During the very early design phase of Objective-C, it was decided that objects would be a purely heap-based pointer design, so that they could be passed between any function without weird copy semantics and such (this changed a bit with Obj-C++ and ARC, but that's too wide of a scope for this post), and that every method should be self aware (acually, as bbum points out, it was an optimization for using the same stack frame as the original function call), so that you could have, in theory, multiple method names mapped to the same selector, as follows:
// this is a completely valid objc 1.0 method declaration
void *nameOrAge(id self, SEL _cmd) {
if (_cmd == #selector(name)) {
return "Richard";
}
if (_cmd == #selector(age)) {
return (void *) (intptr_t) 16;
}
return NULL;
}
This function, then could be theoretically mapped to two selectors, name and age, and perform conditional code based on which one is invoked. In general Objective-C code, this is not too big of a deal, as it's quite difficult with ARC now to map functions to selectors, due to casting and such, but the language has evolved quite a bit from then.
Hopefully, that helps you to understand the why behind the two 'invisible' arguments to an Objective-C method, with the first one being the object that was invoked, and the second one being the method that was invoked on that object.
The first two arguments are the hidden arguments self and _cmd.

Is Objective-C converted to C code before compilation?

I know objective C is strict superset of C and we are writing the same thing.
But when i write
#interface Myintf {}
#end
Does it get converted to a C struct or is it that the memory layout for the data structure Myintf prepared by Objective c compiler is same as that of a C struct defined in runtime.h?
and same question about objc_msgsend
Apple document says
In Objective-C, messages aren’t bound to method implementations until runtime. The compiler converts a message expression, into a call on a messaging function, objc_msgSend. This function takes the receiver and the name of the method mentioned in the message—that is, the method selector—as its two principal parameters:
Does it get converted to a C struct
In the old days it used to, but with the modern runtime (OS X 10.5+ 64 bit and iOS), I think it's a bit more complicated. It can't be using a traditional struct because the Fragile Instance Variable problem is solved.
and same question about objc_msgsend
Yes. All method invocations - or more correctly, all message sends - are converted into calls to obj_msgsend() (except for when super is used as the receiver when a different C function is used).
Note that early implementations of Objective-C were implemented as a preprocessor and produced C source code as an intermediate step. The modern compiler does not bother with this and goes straight from Objective-C source code to an object code format.
No and no. Both cases ultimately rely on the runtime. In a way, it is converted to use C interfaces, but there is a level of abstraction introduced -- it's not entirely static.
It will help to look at the assembly generated by the compiler to see how this works in more detail.
Given the declaration:
id objc_msgSend(id theReceiver, SEL theSelector, ...);
The compiler inserts a call to objc_msgSend when your implementation calls a method. It is not reduced to a static C function call, but dynamic dispatch -- another level of indirection, if you like to think of it that way.

Why is everything a pointer in Objective-C

I come from a PHP/Javascript background where things are stored in a variable directly in most cases, where we also had Object/Classes/Methods, etc. It was OOP.
Now I'm starting to learn Objective-C. I understand the basics of pointers. But everything is a pointer now. This is the part that I don't get. Why aren't we like in PHP/Javascript with direct assignment? We are still doing OOP afterall.
Thanks
If you look at the semantics of JavaScript and many other OO languages (perhaps including PHP, but I'm not sure and not willing to guess), you'll see that these languages offer the same indirection Objective C offers through pointers. In fact, internally these languages use pointers everywhere. Consider this (JavaScript) snippet:
function f(obj) {
obj.x = 1; // modifies the object referred to directly
obj = {x: 2}; // doesn't affect caller
}
var foo = {x: 0};
f(foo); // passes a pointer/"reference"
// foo.x === 1
It's roughly equivalent to (C as I don't know Objective C) something like this, modulo manual memory management, static typing, etc.:
struct Obj { int x; };
void f(struct Obj *obj) {
obj->x = 1;
obj = ...; // you get the idea
}
struct Obj *foo = malloc(sizeof(*foo));
foo->x = 0;
f(foo);
free(foo);
It's just explicit in Objective C because that language's a superset of C (100% backwards compability and interoperability), while other languages have done away with explicit pointers and made the indirection they need implicit.
In PHP you also work only with pointers but transparently.
Really you using references to objects
The reason why the designers of Objective-C decided to go with using pointers on everything that is an Objective-C object include the following:
So they can deal with behind the scenes memory management without taking away the programmers ability to do so on his own.
Fast Enumeration on objects.
(Perhaps the most important) Gives the ability to have id types that can pass nil(null) values without crashing the program.
To build on the other answers here: in PHP and other languages you are still using pointers. That is why there is still a distinction between passing by reference and passing by value. There are several good sites that help explain the distinction, both in syntax and what it means to pass by either method.
Edit:
Refer to the second link in my post. My interpretation of that information is that PHP passes by value by default. Adding the ampersand in front of the variable during the function call passes a reference (or rather the address of the variable). In essence, passing by reference is passing a pointer while passing by value does a copy of the value completely. They also have different implications on their usage (reference allows modifying the original variable's value, even outside the scope of the function etc).
Objective C is a strict superset and extension of ANSI C, so the native types that could be compatibly added to the language were constrained (perhaps by the original implementation). But this compatibility with ANSI C has turned out to be one of the advantages of using Objective C mixed with the reuse of cross-platform C code.
BTW, OOP and "safety" are nearly orthogonal concepts. They each have different potential costs in terms of consuming CPU cycles and/or eating the user's battery power.
Objects are created using the +alloc method, which allocates space for the new object on the heap. In C, and therefore in Objective-C, the only way to refer to memory on the heap is through a pointer.

What is this objective-c function construct called?

I was looking through one of Apple's XCode tutorials and came across something that looked like this inside the implementation of a class method:
void (^foo)(void);
foo = ^(void) {
NSLog(#"Hello, World!");
};
foo();
Now obviously this is some kind of function declaration, implementation, and usage. However, I'd like to know more about it, what it is called, and what its limitations and advantages are. My searches online are turning up nothing relevant. Can anyone point me in the proper direction?
They're called blocks. You can think of a block as a chunk of code that you can pass around to other parts of your program. They were added by Apple to its C and Objective-C compilers relatively recently, but some newer APIs take blocks instead or in addition to selectors or function pointers.
Blocks and block variables.
Here's some reading:
http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/Blocks/Articles/00_Introduction.html
http://pragmaticstudio.com/blog/2010/7/28/ios4-blocks-1
http://thirdcog.eu/pwcblocks/