Gürhan KODALAK
Gürhan KODALAK

Reputation: 580

NSArray alloc and init

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

Answers (2)

Rob Napier
Rob Napier

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

Azat
Azat

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

Related Questions