While reading through the blocks conceptual overview in Apple Docs, I saw the following statement:
Although blocks are available to pure C and C++, a block is also
always an Objective-C object.
How is this possible? I mean an Objective-C object available in pure C. I'm getting confused.
How is this possible? I mean an Objective-C object available in pure C.
Matt Gallagher wrote an article that nicely explains how blocks work. In a nutshell, blocks are defined as structs that meet the requirements to be a valid Objective-C object (for example, the struct starts with an isa pointer). None of this causes a problem for C, and the compiler knows what the definition of a block is, so even when compiling plain old C it can still do the right thing to make blocks work.
The added Objective-C aspect of blocks doesn't affect how blocks are used in C, but still provides the ability to treat blocks as objects so that they can be added to collections and otherwise managed like any other object.
This isn't really so strange. If you think about it, all Objective-C objects are "available" in C at some level -- the entire Objective-C runtime consists of C functions that manipulate structures that represent Objective-C objects and classes. And even disregarding that, blocks aren't the first example of a data type that's usable in both C and Objective-C -- we've had toll free bridging between Foundation and Core Foundation for many years. The implementation of blocks may be somewhat different, but it's not a new thing to have objects that work in both worlds.
Objective-C can be freely mixed with C. As long as your class has a C API (which blocks do, with Block_copy, Block_release, etc.), the C code doesn't care if it's implemented in Objective-C or C.
From the same document,
float (^oneFrom)(float);
oneFrom = ^(float aFloat) {
float result = aFloat - 1.0;
return result;
};
oneFrom a variable referencing the block (object) { float result = aFloat - 1.0; return result; }
Blocks are available to pure C and C++, ie. the block can consist of pure C or C++ code.
Related
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.
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.
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.
Thank you to Yuji for answering another question I had and pointing me to this article about dynamic ivars in Objective-C.
However, as explained in my other question the sizeof operator now behaves inconsistently. In short, sizeof will not take into account dynamic ivars from outside the class .m file but will take them into account inside the .m file after the #synthesize declarations that create the dynamic ivars.
So my question is does this break the idea that Objective-C is a strict superset of C?
No. All valid C code remains valid Objective-C code with the same meaning it has in C, so Objective-C is still a strict superset. Keep in mind that a superset is allowed to have features not found in a subset — that's the whole reason Objective-C can have all the additional capabilities and syntax that it does while remaining 100% C-compatible.
What this does affect is the implementation detail that Objective-C classes are essentially C struct types with a set of functions that act on them. Note that similar functionality to objC_setAssociatedObject() could be implemented for a CoreFoundation-style pure C struct without changing the C language itself at all — and it would have the similar side effect of making sizeof() not give a fully "accurate" idea of all the data the struct encompasses.
No. If you run Objective-C code through a C compiler it never would have compiled anyway. If you run C code through an Objective-C compiler it will behave exactly as if you had run it through a C compiler (barring compiler bugs).
If you ever find yourself writing sizeof(MyObjectiveCClass) you are almost certainly doing something horribly wrong that will be completely broken.
I have just started to learn Objective - C. I have done one year of Java programming and one year of Actionscript. I need to find a website or blog which tells me how to do the basic things for example declare a variable or how to write a method and function. I cant seem to find this anywhere. If someone could give me some good links that would be great.
Thanks
Introduction to The Objective-C 2.0 Programming Language from Apple would probably be a good place to get started with the Objective-C language.
In general, declaring variables aren't too different within a method.
-(void)doSomething {
// Declaration of a variable.
int myVariable = 0;
}
The syntax for methods and functions can be a little bit different, and the language itself allows the use of C, as Objective-C is a superset of C.
One conceptual difference about classes and objects in Objective-C compared to Java is that the implementation and the declaration is separated into two different files. The "header" information which defines the interface is usually included in the .h file, while the implementation is included in the .m file.
The interface defines the methods, properties and such, while the implementation includes the actual code to use in the methods.
Also, strictly speaking, in Objective-C are not "methods" are not "called", but "messages" are "sent" to objects, and the objects react to them:
// The following is sending the "doSomething" message to "myObject".
// Strictly speaking, it's not a method call, but a messaging of an object.
[myObject doSomething];
Also, the Wikipedia article on Objective-C also gives a pretty good overview of the language as well.
I would highly recommend the book Programming in Objective-C 2.0 by Stephen Kochan.
I used the older version when I was learning Objective-C and still reference it on occasion. It is an excellent introduction to the basics of the language.