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.
Related
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.
While working on on open source project, I came across the following C function declaration and implementation:
// FSNData.h
NSString *stringForMimeType(MimeType type);
#interface FSNData : NSObject
// All the expected objective-c property and instance method declarations
#end
// FSNData.m
#import "FSNData.h"
// where 'type' is an enum
// this does work as expected
NSString *stringForMimeType(MimeType type) {
switch (type) {
case MimeType_image_jpeg: return #"image/jpeg";
case MimeType_image_png: return #"image/png";
default:
NSLog(#"ERROR: FSNData: unknown MimeType: %d", type);
// do not return "application/octet-stream"; instead, let the recipient guess
// http://en.wikipedia.org/wiki/Internet_media_type
return nil;
}
}
#implementation
// all properties and methods defined in FSData.h implemented as expected
#end
This example could easily be re-written as a class level method with out any problem. As it is, using stringFormMimeType() sill requires importing the FSNData header file anyway.
Looking at the Apple docs, it states only:
Because Objective-C rests on a foundation of ANSI C, you can freely
intermix straight C code with Objective-C code. Moreover, your code
can call functions defined in non-Cocoa programmatic interfaces, such
as the BSD library interfaces in /usr/include.
There is no mention of when C functions should favour Objective-C methods.
The only benefit I can see at this point, is that calling the above function, as opposed to a class method, some Objective-C runtime call(s) would be skipped. In a typical use case of FSNData, this would not give a noticeable boost in performance to the user (probably even to developers)*.
What benefit exists (other than coding style) for favouring a C function over a class method?
*FSNData is used as part of the FSNetworking library, so I doubt there would be thousands upon thousands of network operations being performed during any application's life cycle.
In short, C (or C++) implementations are very useful:
For Abstraction
For Reusability
When making medium and large scale programs
In performance critical paths
For 'Interior' implementations
What benefit exists (other than coding style) for favouring a C function over a class method?
ObjC messaging introduces indirect function calls. These are firewalls for optimizers.
C functions can easily restrict access, whereas 'private' ObjC implementations may be looked up using the ObjC runtime, or accidentally overridden.
C functions may be removed from your executable if not referenced, or they may be made private. If you write reusable code (and you should), this can have a huge impact on your binary sizes and load times -- C functions which are not referenced/used may be removed, but ObjC types and methods will be preserved (including everything they reference). This is why your app's binary size may grow significantly when you use only small part of an ObjC static library -- every objc class in the library is preserved. If that library were C or C++, then you could get by with very small growth because you need only what is referenced. What is or is not referenced is easier to prove with C and C++.
C functions can be inlined, either during compilation or during Link Time Optimization phases.
The compiler and optimizers are able to do much optimization with C functions (e.g. inter-procedural optimizations), but very little with ObjC methods because they are always indirect.
To avoid ObjC message dispatch overhead (as you mentioned)
Potential for additional reference counting operations and autorelease pool activity when interacting with ObjC objects.
Of course you won't always hurt paying for things you don't need or use -- and remember that ObjC class methods have some benefits over C functions, too. So, just look at C or C++ implementations as another tool in your toolbox. I find them very useful as complexity and project sizes increase, and they can be used to make your programs much faster. Just do what you are least likely to regret in 2015 ;)
You already touched on the marginal performance difference of avoiding an objc_msgSend call. Objective-C class methods are also subject to overriding in subclasses, so implementing a method in C will prevent it from being overridden in a subclass. Relatedly, because of that runtime inheritance/polymorphism, an Objective-C method can never be inlined, whereas a C function can potentially be inlined by the compiler for added performance.
When it comes to avoiding objc_msgSend, a wise man once told me, "If the overhead of objc_msgSend is too great for you, Objective-C is probably the wrong tool for the job."
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.
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.
I'm starting to code in objective-c and I've just realized that objects can only be passed by reference.
What if I need an object to use static memory by default and to be copied instead of referenced?
For example, I have an object Color with 3 int components r, g and b. I dont want these objects to be in dynamic memory and referenced when passing to functions, I want them immutable and to be copied like an int or a float.
I know I can use a c struct, but I also need the object Color to have methods that gets/sets lightness, hue, saturation, etc. I want my code to be object oriented.
Is there any solution to this?
EDIT: If for example I'm building a 3d game engine, where I'll have classes like Vector2, Vector3, Matrix, Ray, Color, etc: 1) I need them to be mutable. 2) The size of the objects is roughly the same size of a pointer, so why would I be copying pointers when I can copy the object? It would be simpler, more efficient, and I wouldnt need to manage memory, specially on methods that returns colors. And In the case of a game engine, efficiency is critical.
So, if there is no solution to this... Should I use c-structs and use c-function to work on them? Isn't there a better choice?
Thanks.
You can't do this. This isn't how Objective-C works (at least the Apple/GNU version*). It simply isn't designed for that sort of extreme low-level efficiency. Objects are allocated in dynamic memory and their lifetimes are controlled by methods you call on them, and that's just how it works. If you want more low-level efficiency, you can either use plain C structs or C++. But keep in mind that worrying about this is pointless in 99% of circumstances — the epitome of premature optimization. Objective-C programs are generally very competitive with C++ equivalents both in execution speed and memory use despite this minor inefficiency. I wouldn't go for a more difficult solution until profiling had proved it to be necessary.
Also, when you're new to Objective-C, it's easy to psych yourself out over memory management. In a normal Cocoa (Touch) program, you shouldn't need to bother about it too much. Return autoreleased objects from methods, use setters to assign objects you want to keep around.
*Note: There was an old implementation of Objective-C called the Portable Object Compiler that did have this ability, but it's unrelated to and incompatible with the Objective-C used on Macs and iOS devices. Also, the Apple Objective-C runtime includes special support for Blocks to be allocated on the stack, which is why you must copy them (copy reproduces the block in dynamic memory like a normal object) if you want to store them.
What if I need an object to use static memory by default and to be copied instead of referenced?
You don't.
Seriously. You never need an object to use static memory or be allocated on the stack. C++ allows you to do it, but no other object oriented language I know does.
For example, I have an object Color with 3 int components r, g and b. I dont want these objects to be in dynamic memory and referenced when passing to functions, I want them immutable and to be copied like an int or a float.
Why do you not want the objects to be in static memory? What advantage do you think that gives you?
On the other hand it's easy to make Objective-C objects immutable. Just make the instance variables private and don't provide any methods that can change them once the object is initialised. This is exactly how the built in immutable classes work e.g. NSArray, NSString.
One solution that people use sometimes is to use a singleton object (assuming you only need one of the objects for your entire app's lifetime). In that case, you define a class method on the class and have it return an object that it creates once when it is first requested. So you can do something like:
#implementation MyObject
+ (MyObject *)sharedObjectInstance
{
static MyObject *theObject=nil;
if (theObject==nil)
{
theObject = [[MyObject alloc] init];
}
return theObject;
}
#end
Of course the object itself isn't what's being statically allocated, it's the pointer to the object that's statically allocated, but in any case the object will stick around until the application terminates.
There are times when you want to do this because you really only want one globally shared instance of a particular object. However, if that's not your objective, I'm not sure why you'd want to do what you're describing. You can always use the -copy method to create a copy of an object (assuming the object conforms to the NSCopying protocol) to manipulate without touching the original.
EDIT: Based on your comments above it seems you just want to have immutable objects that you can copy and modify the copies. So using -copy is probably the way to go.