What is the different between this:
id:
#import <objc/Object.h>
@interface Forwarder : Object
{
id something;
}
NSObject:
#import <objc/Object.h>
@interface Forwarder : Object
{
NSObject *something;
}
Thz u.
“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 supertype of all objects.
id is a language keyword but the NSObject is the base class in objective c. For id, you dont need to typecast the object. But for NSObject, you have to typecast it into NSObject.
In Swift 3, the id type in Objective-C now maps to the Any type in Swift, which describes a value of any type, whether a class, enum, struct, or any other Swift type.
Creating a Custom Class Go ahead an choose “Objective-C class” and hit Next. For the class name, enter “Person.” Make it a subclass of NSObject. NSObject is the base class for all objects in Apple's developer environment. It provides basic properties and functions for memory management and allocation.
This Greg MILLER's blog post from the unixjunkie blog sums up the differences
Some extracts:
There's often confusion about the difference between the following three declarations in Objective-C:
id foo1;
NSObject *foo2;
id<NSObject> foo3;
The first one is the most common.
It simply declares a pointer to some Objective-C object (see/usr/include/objc/objc.h
). id gives the compiler no information about the actual type of the object, so the compiler cannot do compile-time type checking for you.Just because we know that an id is an Objective-C object does not mean that it points to an object that derives from
NSObject
, or that it even has common methods like retain and release.
One solution is to statically type our variable usingNSObject*
as shown in number 2 above.
This gives the compiler information about the class of the object pointed to by foo2 so the compiler can warn if you send a message to foo2 that anNSObject
doesn't respond to. This means you can safely call retain, release, description, etc., but the compiler will warn if you call length or count or anything that anNSObject
doesn't respond to.Declaring an object as
id<NSObject>
tells the compiler that you don't care what type the object is, but you do care that it conforms to the specifiedNSObject
protocol**
.**
the protocol (@protocol
) namedNSObject
. There is also a class namedNSObject
that does indeed conform to theNSObject
protocol, but they are two different thing
The compiler will ensure that all objects you assign to that pointer conform to the required protocol.
A pointer typed like this can safely hold anyNSObject
(becauseNSObject
conforms to theNSObject
protocol), but it could also hold anyNSProxy
, becauseNSProxy
also conforms to the NSObject protocol.
In english, the declarationid<NSObject>
foo3; says "foo3 is a pointer to an object of any type that behaves like an NSObject".
This is very powerful, convenient, and expressive. In reality, we often don't care what type an object is, we just care that it responds to the messages that we want to send it (e.g., retain, release).
If you don't want (or can't have) any type checking, then use a plain id. This is very common for return types on methods that don't know the type of object they're returning (e.g., +alloc). It is also common to declare delegates to be type id, because delegates are generally checked at runtime with respondsToSelector:, and they usually aren't retained.
However, if you do want compile-time type checking, you must decide between the second and third cases. Well, let me just help you out—you want the third case! :-) I've very, very, VERY rarely seen a situation where NSObject * worked but id would not. And using the protocol form has the advantage that it will work with NSProxys.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With