Is id in Objective C is primitive data type - objective-c

I am bit confused, as my title mentioned,
Is id in Objective C is primitive data type? or Object type? I always thought that id is Object type as it is pointing towards an object.
So, Is it Object type or Primitive data type?

Definitly not a primitive type. From Apple:
In Objective-C, object identifiers are of a distinct data type: id. This type is the general type for any kind of object regardless of class and can be used for instances of a class and for class objects themselves.

id is declared in objc.h as
typedef struct objc_object {
Class isa;
} *id;
so yes, I'd say it's primitive (pointers are primitive types in C).

I believe that 'id' from Objective-C is a similar type to void pointer from plain 'c'. As pointers are primitives I would guess that 'id' is indeed a primitive type.

Related

What is the difference between int *p; and ClassA *Obj?

Could anybody explain me the difference between the pointer concept when using primitive datatypes like int and Objective-C data types like NSString?
thanks,
bala
Pointers are just that. They locate a memory location. You de-reference that pointer(location) to either primitive data type or user defined types as appropriate. I don't see a difference b/w pointers to user defined and primitive data types.
Assuming both pointer had been initialised properly dereferencing the former gives you an int, whereas doing so to the latter gives you a ClassA.
So in fact there is no difference, but the data instance those pointers are referring to.

confusion regarding "id" in obj-c programming guide of Apple

id
In Objective-C, object identifiers are of a distinct data type: id. This type is the general type for any kind of object regardless of class and can be used for instances of a class and for class objects themselves.
id anObject;
Till here its simple and clear
For the object-oriented constructs of Objective-C, such as method return values, id replaces int as the default data type. (For strictly C constructs, such as function return values, int remains the default type.)
didn't understand what its talking about id replaces int? and in last inside brackets int remains the default value?
The keyword nil is defined as a null object, an id with a value of 0. id, nil, and the other basic types of Objective-C are defined in the header file objc/objc.h.
id is defined as pointer to an object data structure:
typedef struct objc_object {
Class isa;
} *id;
the above is not a obj-c syntax what is it and what it is explaining?
Every object thus has an isa variable that tells it of what class it is an instance. Since the Class type is itself defined as a pointer:
typedef struct objc_class *Class;
the isa variable is frequently referred to as the “isa pointer.”
also didn't understand this last para.
For the object-oriented constructs of Objective-C, such as method return values, id replaces int as the default data type. (For strictly C constructs, such as function return values, int remains the default type.)
Your book's just being a bit confusing here. All it's saying is that if you're working with objects and you don't want to get more specific, id is a good data type to use.
id is defined as pointer to an object data structure:
typedef struct objc_object {
Class isa;
} *id;
the above is not a obj-c syntax what is it and what it is explaining?
That's the internal representation of an object. Your book is trying to show that an objective C object isn't magic: under the surface it's just a struct. The data type id is a pointer to such a struct.
Every object thus has an isa variable that tells it of what class it is an instance. Since the Class type is itself defined as a pointer:
typedef struct objc_class *Class;
the isa variable is frequently referred to as the “isa pointer.”
In its internal data structure, each object has a pointer to another object that represents its class.
You don't need to know this stuff if you're just interested in programming in Objective-C (at least not while you're learning). It does come in handy if you're doing some advanced stuff, such as when you're interacting with the Objective-C runtime directly.
didn't understand what its talking about id replaces int?
Objective-C is a superset of C.
In C, a function must have a return value. If a return value is not specified, then a function returns int by default.
Objective-C overrides this default behaviour of C and returns id as a default value from any class method that doesn't specify its return value. But at the same time leaves the default behaviour for other (C-)functions the same (i.e. int is still the default return value for everything else)

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?

Why id is generic pointer?

I want to know why id is a weak reference pointer,how it is able to handle any class type pointer and at run time how can we detect that which type of class pointer is assigned to id.
Why is id a weak reference pointer?
id is not a weak reference pointer, at least not in the ARC ownership sense. Whether an id-typed reference to an object is weak or not depends on the reference having been declared __weak (and variations) and the object’s class actually supporting weak references.
However, you could say that id provides weak typing, although I think that dynamic/duck typing is a more accurate description. Since an id- typed reference contains no compile-time class-type information, the compiler isn’t able to, for example, determine if the underlying object can respond to a given selector, which could lead to runtime errors.
How is it able to handle any class type pointer?
That’s part of the definition of the Objective-C language. The compiler recognises id as being the supertype of every Objective-C class, and it treats id differently. See the answer below as well.
At runtime, how can we detect that which type of class pointer is assigned to id?
In Apple’s Objective-C runtime, the first bytes in the memory allocated to an object must point to that object’s class. You might see this referenced elsewhere as the isa pointer, and that’s how Apple’s runtime finds out the class of every1 object. The id type is defined to have this information as well. In fact, its only attribute is the isa pointer, which means that all1 Objective-C objects conform to this definition.
If you have an id reference and want to discover the class of the referenced object, you can send it -class:
id someObject;
// Assign something to someObject
// Log the corresponding class
Class c = [someObject class];
NSLog(#"class = %#", c);
// Test whether the object is of type NSString (or a subclass of NSString)
if ([someObject isKindOfClass:[NSString class]]) {
NSLog(#"it's a string");
}
1Tagged pointers are a notable deviation of this structure, and (partly) because of them one shouldn’t access the isa pointer directly.
It's nice to have a generic object type, so you can define collection types that can hold any kind of object, and other generic services that work with any object without knowing what kind of object it is.
There is no trick to make id work. At a binary level all pointers are interchangeable. They just represent a memory address as a numerical value. To make id accept any type of pointer, it's only necessary to disable the rules of the compiler that normally require pointer types to match.
You can find out information about the class of an id type variable in these kinds of ways:
id theObject = // ... something
Class theClass = [theObject class];
NSString *className = NSStringFromClass(theClass);
NSClassDescription *classDescription = [NSClassDescription classDescriptionForClass:theClass];
But it's rarely necessary to do those kinds of things in code. More often, you want to test if your id variable is an instance of a particular class, and if so cast it to that class and start treating it as that type.
if ([theObject isKindOfClass:[MySpecializedClass class]]) {
MySpecializedClass *specialObject = (MySpecializedClass *)theObject;
[specialObject doSomethingSpecial];
}
If you were to use -class to find out the class, but it returned a class you know nothing about, then there's nothing special you can do with the object based on its class anyway. So there is no reason to do anything but check if it matches classes you know about, and only if you intend to do special handling for those classes anyway.
You can sometimes use isMemberOfClass instead of isKindOfClass. It depends whether you want an exact match or to include subclasses.
It may be worth to take a look on header file objc/objc.h to find internals of id.
typedef struct objc_class *Class;
typedef struct objc_object {
Class isa;
} *id;
typedef struct objc_selector *SEL;
typedef id (*IMP)(id, SEL, ...);

Objective-C: Casting objects retrieved from collection

In Objective-C, when retrieving objects from a collection (for example, using -[NSArray objectAtIndex:]), when does the object need to be cast to its original class, and why?
It seems like when calling methods the cast isn't necessary but it is when using property dot notation. But I don't understand exactly why this is.
You need to cast it when using dot notation because of a simple thing: otherwise the compiler treats it as a struct objc_object { Class isa; } *, which hasn't got the member you want to get. (In fact, to access isa you need the ->-notation anyway.)
This is basically because -[NSArray objectAtIndex:] returns id, which is defined as:
typedef struct objc_object { Class isa; } *id;
You need to cast it in order to use dot notation, but you don't need to cast it to send messages to it. My approach: always cast. :)