I have the following code:
id anArray = [NSArray arrayWithObjects:@1, @2, nil];
NSLog(@"anArrayClass - %@", [anArray class]);
NSLog(@"NSArrayClass - %@", [NSArray class]);
And I expect both output are NSArray
, however the output turns out to be:
2016-08-18 21:08:53.628 TestUse[9279:939745] anArrayClass - __NSArrayI
2016-08-18 21:08:53.629 TestUse[9279:939745] NSArrayClass - NSArray
Then I create a test class called CAJTestClass
and create an instance of that class:
id testInstance = [CAJTestClass new];
NSLog(@"testInstanceClass - %@", [testInstance class]);
NSLog(@"cajTestClass - %@", [CAJTestClass class]);
This time the output becomes:
2016-08-18 21:08:53.629 TestUse[9279:939745] testInstanceClass - CAJTestClass
2016-08-18 21:08:53.629 TestUse[9279:939745] cajTestClass - CAJTestClass
This time the result is what I expected. But why would [anArray class]
to be a __NSArrayI
?
An explanation from "Effective Objective-C" is that NSArray
is a part of a "class cluster"(which I think is a series of classes that have inheriting relationships). But CAJTestClass
is also a subclass of NSObject
. Am I wrong?
EDIT: Thanks for all your answers. But my question is exactly why I get different result in this two cases if it should contribute to the affairs of "class cluster"?
Because the test code is completely different. You're calling an
NSArray
method that returns a subclass ofNSArray
, but you're calling[CAJTestClass new]
, which returnsCAJTestClass
itself. If you make them be the same, then you get the same results:Now using your test code:
rmaddy raises the possibility that you have a different question and he may be correct, so I'll answer that one as well.
[anArray class]
is the result of passing the-class
message to the instanceanArray
. The usual thing for an instance to do when it receives the-class
message is to return the specific class it was initialized as (its specific subclass). This is not universal (KVO classes intentionally break this rule and it's even possible to change classes at runtime), but it is the common approach. This is theisa
pointer in the struct that tells the dispatcher which set of methods to use. So you get the actual as-instantiated class object (__NSArrayI
).[NSArray class]
is the result of passing the+class
message to the class objectNSArray
. The usual thing for a class object to is returnself
(I don't know any classes that violate that rule; it may not be legal to violate that rule). So you get the class you passed the message to (NSArray
).