Is there a difference between relating to an Object
in a 'Polymorphic' way with the type id
than as NSObject *
?
In what way is:
NSString* aString = @"Hello";
id anObj = aString;
different than:
NSString* aString = @"Hello";
NSObject* anObj = aString;
id
is generic. By usingid
you're telling the compiler that you will fill in details about usage later. The compiler assumes that any code you have is correct and doesn't warn you about anything. At runtime checks are made to verify what you're trying to do and you will get an exception if your code is wrong.NSObject
is specific. By usingNSObject
you're telling the compiler exactly what the object is. When you try to call methods on it they will be checked against whatNSObject
understands. You will get compile time errors if you make a mistake.All that said, you can just cast in both cases to get to another Class type.
Your concern is what you're going to do with the reference in the future. Generally, using
NSObject
doesn't have any benefits.When using id, you can send it any known message and when using NSObject *, you can only send it messages declared by NSObject (not methods of any subclass) or else it will generate a warning.
id
is a special keyword used in Objective-C to mean “some kind of object.” It does not containisa
pointer(isa
, gives the object access to its class and, through the class, to all the classes it inherits from), So you lose compile-time information about the object.NSObject
containisa
pointer.From Objective-C Is a Dynamic Language
Consider the following code:
In this case, someObject will point to an
NSString
instance, but the compiler knows nothing about that instance beyond the fact that it’s some kind of object. TheremoveAllObjects
message is defined by some Cocoa or Cocoa Touch objects (such asNSMutableArray
) so the compiler doesn’t complain, even though this code would generate an exception at runtime because an NSString object can’t respond toremoveAllObjects
.Rewriting the code to use a static type:
means that the compiler will now generate an error because
removeAllObjects
is not declared in any publicNSString
interface that it knows about.