Reputation: 580
I'm a little confused about NSArray
initialization. The confusing thing is we have different init
methods to init it, and if I just init it without giving any size and any objects, how compiler knows it object count or size in RAM
.
What's the logic/difference behind init method? Can anybody explain it briefly?
Edit:
NSArray *sortedArray = [[NSArray alloc] init];
NSSortDescriptor *descriptor = [[NSSortDescriptor alloc] initWithKey:@"quota" ascending:NO];
NSArray *sortDescriptors = [NSArray arrayWithObject:descriptor];
//How is that possible to modifying to immutable object
sortedArray = [sortedContainers sortedArrayUsingDescriptors:sortDescriptors];
I know the differences between NSArray and NSMutableArray and I'm not looking for the differences. I just wonder how that code can compile/execute without an error.
Upvotes: 0
Views: 4112
Reputation: 299455
[[NSArray alloc] init]
returns an empty, immutable array. There's nothing surprising about that. What else would you return from a method to mean "no items?"
how compiler knows it object count or size in RAM
The object count is 0. It's empty. Its size in RAM is the size of an empty NSArray
. NSArray
is an object, so it has some standard objc_object
overhead, plus some instance variables for NSArray
.
That said, as an implementation detail, Cocoa optimizes this out and always returns the same singleton for all empty NSArray
objects. You can demonstrate this with:
NSArray *a = [[NSArray alloc] init];
NSArray *b = [[NSArray alloc] init];
NSLog(@"%p", a);
NSLog(@"%p", b);
if (a == b) { // Pointer equality, not isEqual:
NSLog(@"Same object");
}
So, what is this doing?
NSArray *sortedArray = [[NSArray alloc] init]; // (1)
// ... code that doesn't matter ...
sortedArray = [sortedContainers sortedArrayUsingDescriptors:sortDescriptors]; // (2)
At line 1, you're creating a local pointer variable, sortedArray
and pointing it to an empty array (it happens to be a singleton, but that's an optimization detail).
At line 2, you create a completely different NSArray
by calling sortedArrayUsingDescriptors:
. You then point sortedArray
at that object. ARC sees that you're no longer pointing at the empty array, and releases it. (Again, optimization details jump in here and the actual steps may be different, but the effect will be the same.)
The correct code here would be:
// ... Code that sets up sortDescriptors ...
NSArray *sortedArray = [sortedContainers sortedArrayUsingDescriptors:sortDescriptors];
Now, in very modern ObjC, you won't see [[NSArray alloc] init]
written out very often. It's easier to write @[]
(which is really just syntactic sugar for a method call). But before array literals were added to language, [[NSArray alloc] init]
or [NSArray array]
were reasonably common.
Upvotes: 5
Reputation: 6795
If you just init NSArray
without giving any size and any objects it will remain empty during lifetime. NSArray
is immutable
If your question is about NSMutableArray
, read here at the SO
Upvotes: 0