Usage of "id" in Objective-C? - objective-c

I have a function that returns "id". Does this include a return of void? (as in nothing) Or does "id" require some kind of object/variable?

In Objective-C, id is a keyword that represents an untyped object pointer. It's kinda like void*, the untyped pointer, but it adds the restriction that the pointer must point to some sort of Objective-C object.

id is a general data type that can wrap most objects. If you can, you usually want to opt for coding specific data types, but if the situation (in a method for example) can use a wide range of data types, id is used.
This Stackoverflow post should help to explain what it is and when to use it. A simple Google search will also turn up information.

In Objective C, id means object of any type, akin to void* in C/C++. You can return nil for from a function returning id to indicate that you do not want to return anything in particular.

'id' is a pointer to an instance of an Objective-C class. So your method can return a pointer to an instance, or 'nil' (a zero pointer).

Related

What is the biggest advantage of using pointers in ObjectiveC

I realize 99% of you think "what the h***…" But please help me to get my head around the this concept of using pointers. I'm sure my specific question would help lots of newbies.
I understand what pointers ARE and that they are a reference to an adress in memory and that by using the (*) operator you can get the value in that address.
Let's say:
int counter = 10;
int *somePointer = &counter;
Now I have the address in memory of counter, and I can indirectly point to its value by doing this:
int x = *somePointer;
Which makes x = 10, right?
But this is the most basic example, and for this case I could use int x = counter; and get that value, so please explain why pointers really are such an important thing in Objective-C and some other languages... in what case would only a pointer make sense?
Appreciate it.
Objective-C has pointers because it is an evolution of C, which used pointers extensively. The advantage of a pointer in an object-oriented language like Objective-C is that after you create an object, you can pass around a pointer to the object instead of passing around the object itself. In other words, if you have some object that takes up a large amount of storage space, passing around a pointer is a lot more memory-efficient than passing around a copy of the object itself. This may not be noticeable in simple cases when you’re only dealing with primitive types like ints, but when you start dealing with more complex objects the memory and time savings are enormous.
More importantly, pointers make it much easier for different parts of your code to talk to each other. If variables could only be passed to functions “by value” instead of “by reference” (which is what happens when you use pointers), then functions could never alter their inputs. They could only change the state of your program by either returning a value or by changing a global variable—the overuse of which generally leads to sloppy, unorganized code.
Here’s a concrete example. Suppose you have an Objective-C method that will parse a JSON string and return an NSDictionary:
+ (NSDictionary *)parseJsonString:(NSString *)json
error:(NSError **)error;
The method will do the parsing and return an NSDictionary if everything goes okay. But what if there’s some problem with the input string? We want a way to indicate to the user (or at least to the programmer) what happened, so we have a pointer to a pointer to an NSError, which will contain that information. If our method fails (probably returning nil), we can dereference the error parameter to see what went wrong. What we’ve effectively done is to give our method two different kinds of return values: usually, it will return an NSDictionary, but it could also return an NSError.
If you want to read more about this, you may have better luck searching for “pointers in C” rather than “pointers in Objective-C”; pointers are of course used extensively in Objective-C, but all of the underlying machinery is identical to that of C itself.
What is the biggest advantage of using pointers in ObjectiveC
I'd say the biggest advantage is that you can use Objective-C at all - all Objective-C objects are pointers are accessed using pointers (the compiler and the runtime won't let you create objects statically), so you wouldn't get any further without them...
Item:
What if I told you to write me a program that would maintain a set of counters, but the number of counters would be entered by the user when he started the program. We code this with an array of integers allocated on the heap.
int *counters = malloc(numOfCounters * sizeof(int));
Malloc works with memory directly, so it by nature returns a pointer. All Objective-C objects are heap-allocated with malloc, so these are always pointers.
Item:
What if I told you to write me a function that read a file, and then ran another function when it was done. However, this other function was unknown and would be added by other people, people I didn't even know.
For this we have the "callback". You'd write a function that looked like this:
int ReadAndCallBack(FILE *fileToRead, int numBytes, int whence, void(*callback)(char *));
That last argument is a pointer to a function. When someone calls the function you've written, they do something like this:
void MyDataFunction(char *dataToProcess);
ReadAndCallBack(myFile, 1024, 0, MyDataFunction);
Item:
Passing a pointer as a function argument is the most common way of returning multiple values from a function. In the Carbon libraries on OSX, almost all of the library functions return an error status, which poses a problem if a library function has to return something useful to the programmer. So you pass the address where you'd like the function to hand information back to you...
int size = 0;
int error = GetFileSize(afilePath,&size);
If the function call returns an error, it is in error, if there was no error, error will probably be zero and size will contain what we need.
The biggest advantage of pointers in Objective-C, or in any language with dynamic allocation, is that your program can handle more items than the names that you invent in your source code.

What is the meaning of id?

I am (trying to) learn Objective-C and I keep coming across a phrase like:
-(id) init;
And I understand id is an Objective C language keyword, but what does it mean to say "the compiler specifically treats id in terms of the pointer type conversion rules"?
Does id automatically designate the object to its right as a pointer?
id is a pointer to any type, but unlike void * it always points to an Objective-C object. For example, you can add anything of type id to an NSArray, but those objects must respond to retain and release.
The compiler is totally happy for you to implicitly cast any object to id, and for you to cast id to any object. This is unlike any other implicit casting in Objective-C, and is the basis for most container types in Cocoa.
id is a pointer to any Objective-C object (objc_object). It is not just a void pointer and you should not treat it as so. It references an object that should have a valid isa pointer. The values that can be stored in id are also not just limited to NSObject and its descendants, which starts to make sense of the existence of the NSObject protocol as well as the NSProxy class which does not even inherit from NSObject. The compiler will allow you to assign an object referenced by type id to any object type, assign any object type to id, as well as send it any message (that the compiler has seen) without warning.
id is a generic type. This means that the compiler will expect any object type there, and will not enforce restrictions. It can be useful if you're expecting to use more than one class of objects there; you can then use introspection to find out which class it is. id automatically assumes a pointer, as all objects in Objective-C are passed as pointers/references.
Some Additional Resources:
id vs NSObject vs id*
Objective-C Programming (Wikibooks)
Introspection
Dynamic Typing
id is a data type of object identifiers in Objective-C, which can
be use for an object of any type no matter what class does it have.
id is the final super type of all objects.
In java or c# we use like this
Object data = someValue;
String name =(Object)data;
but in objective c
id data= someValue;
NSString *name= data;
Yes and no. It's true that having id x designates x as a pointer, but saying that the pointer type conversion rules apply is wrong, because "id" has special type conversion rules. For example, with a void * pointer you can't do this:
void *x;
char *y = x; // error, this needs an explicit cast
On the contrary, it's possible with id:
id x;
NSString *y = x;
See more usage of type id in objective c examples.
In addition in the "modern" Objective C it's preferred to use instancetype instead of "id" on "init" methods. There's even an automatic conversion tool in Xcode for changing that.
Read about instancetype: Would it be beneficial to begin using instancetype instead of id?

Should I be casting when returning id from an objective-c method or not?

For the Objective-C gurus:
Suppose I have a simple method like so:
-(id)getValue{ return [NSNumber numberWithDouble:5.0]; }
Now, suppose within some other method I call the (id)getValue method like so:
NSNumber* myValue = [self getValue];
or what if I call it like this instead:
NSNumber* myValue = (NSNumber*)[self getValue];
The question is: Obviously these lines are equivalent but one of them utilizes an explicit cast. So what is the correct or best-practice way of doing this. It seams to me the cast is unnecessary since when it is placed in the pointer myValue, it will be type-safe at this point anyways (which is something I want) so the cast is basically pointless.
Let me just add that I'm sure people will point out: Why don't you just return (NSNumber*) from the getValue method but in my case I want to have the flexibility to return whatever I want much like the built in NSDictionary class returns id when you call: objectForKey because it allows you to place any type of NSObject or subclass inside of it. In other words my getValue method will not always be returning an NSNumber. Also consider this example is contrived because I am just concerned about whether to cast or not.
Thank you in advance,
-Ralph
The only reason to cast objects is to make the compiler happy. (Sometimes it also helps readability.) For example, you have to cast when making a property access directly on an object you're getting out of an array or dictionary:
((Foo *)[myArray objectAtIndex:0]).bar;
If you don't do the cast, the compiler can't do the property lookup, and will complain.
When you're getting an object from a method that returns id, it's impossible for the compiler to know what its actual type is. There isn't really any "type-safety", because id is a generic pointer; all the compiler can and will enforce is that the method says it returns some Objective-C object. It is perfectly happy to assign a generic pointer to any typed pointer.* (This is actually an advantage for containers, obviously.) Since the type of the variable to which you're assigning already documents the actual return type, I'd say there's no need for the cast.
As an aside, you shouldn't be calling your method getX. That has a specific meaning in Cocoa; methods which "get" something pass in a pointer to a pointer, which is then filled by the method. See -[NSArray getObjects:range:] as an example.
*The type will be enforced at run-time, of course, in the sense that sending messages to which the object does not respond will cause an error.

Why do functions use -(void) and not -(nil) in Obj-C?

In objective-C I often see functions that don't return anything declared as:
- (void)myFunction {…
But why aren't functions declared using nil, like this
- (nil)myFunction {…
Don't they both return "nothing"?
void is nothing. nil is something (0).
In other words, returning nil isn't the same as returning nothing.
Historically in languages belonging (syntactically) to the C-like language family, void indicates that there is no type being returned from a function.
More precisely, just as variables have (or belong to) a given type, functions also have types. For example, a function that returns a int, it is an int type function, or a function whose type is int. Same if it returns something else.
If the function does not return anything - it returns nothing - what type does it belongs to? It has no type, and the void type represents such a thing.
I'm not versed in Objective C, but if I understand correctly, nil is an typeless ID (or an id of any type), almost like a built-in implementation of the null pattern.
And null is a (void *) type, the later being a typeless pointer that can point to anything, just as it would in C and C++.
So a function that returns nil would imply that its type is an id of any type. Don't know if that even makes sense. So right then and there, (nil)myFunction is of a type completely different from (void)myFunction since the former has one type (any type?) whereas the later has no type at all.
Also, nil is a built-in constant. Returning nill is like saying that your function returns a specific number for instance ((1)myFunction). That wouldn't make any sense, would it?
Void is an object type. Void means there is no return value.
Nil is an object, not a type. It represents an empty value.

What is the difference between *(id *)((char *)object + ivar_getOffset(ivar)) and object_getIvar(object, ivar)

According the Objective-C runtime reference:
ivar_getOffset
Returns the offset of
an instance variable.
ptrdiff_t ivar_getOffset(Ivar ivar)
Discussion For instance variables of
type id or other object types, call
object_getIvar and object_setIvar
instead of using this offset to access
the instance variable data directly.
Declared In runtime.h
Why is this? What does object_getIvar do to object types?
EDIT: changed question from subscripting (void *) to (id *).
There is no difference between those two approaches when it comes to getting the value of the ivar. You can verify this by looking at object_getIvar()'s implementation in Apple's open-source Obj-C runtime code.
object_setIvar() does more than just assign to an offset from the object pointer. It is careful to call through to the garbage-collection runtime function objc_assign_ivar() to perform the actual assignment.
More magic might be added to either of these functions in future; in general, you should use the highest-level API available at any given time.
Perhaps it's not that object_getIvar does something different, but that instance variables of type id or other object types are commonplace, and that calling ivar_getOffset and appending the result to the value of object and then casting to the appropriate type is much more cumbersome.
Note that you cannot reliably increment the value of a void *, based on the following information from the C99 standard (emphasis mine):
C99 §6.2.5 (1): (...) Types are partitioned into object types (types that fully describe objects), function types (types that describe functions), and incomplete types (types that describe objects but lack information needed to determine their sizes).
C99 §6.2.5 (19): The void type comprises an empty set of values; it is an incomplete type that cannot be completed.
C99 §6.5.6 (2): For addition, either both operands shall have arithmetic type, or one operand shall be a pointer to an object type and the other shall have integer type. (Incrementing is equivalent to adding 1.)
C99 §6.5.2.1 (1): One of the expressions shall have type “pointer to object type”, the other expression shall have integer type, and the result has type “type”.
To increment a pointer by an arbitrary number, you can use char * instead.