iOS Gotcha: Empty NSArray Optimization
I got bitten by a little iOS optimization the other day. It turns out, that NSArray has been optimized to represent the empty array with the same singleton object, no matter how instantiated.
This code:
NSArray *a1 = [[NSArray alloc] init]; NSArray *a2 = [[NSArray alloc] init]; NSLog(@"a1 == a2 => %d", (a1 == a2));
says:
a1 == a2 => 1
which indicates, that even though it looks like we instantiate 2 objects, the “a1″ and “a2″ variables point to the same object.
It doesn’t matter much how we instantiate the empty NSArray. We could also do:
NSArray *emptyArr = [[NSArray alloc] init]; NSArray *a1 = [NSArray arrayWithArray:emptyArr]; NSArray *a2 = [NSArray arrayWithArray:emptyArr]; // or NSArray *a1 = [NSArray array]; NSArray *a2 = [NSArray array]; // or NSArray *a1 = [NSArray arrayWithObjects:nil]; NSArray *a2 = [NSArray arrayWithObjects:nil];
I guess it is because NSArray is immutable, that this optimization was found okay to make. If I add just one object, I can’t reproduce it. So this:
NSArray *a1 = [NSArray arrayWithObject:@"foo"]; NSArray *a2 = [NSArray arrayWithObject:@"foo"]; NSLog(@"a1 == a2 => %d", (a1 == a2));
yields:
a1 == a2 => 0
and maybe more surprising, this code:
NSArray *a1 = [NSArray arrayWithObject:@"foo"]; NSArray *a2 = [NSArray arrayWithArray:a1]; NSLog(@"a1 == a2 => %d", (a1 == a2));
also yields:
a1 == a2 => 0
I would’ve guessed, that “[NSArray arrayWithArray:a1]” simply returned “a1″, because after all, NSArray is immutable. But it seems not to, when the given array isn’t an empty array.
Anyways, I got bitten because I had some code in a setter method with an optimization that went something like this:
if (_ivarArray != newArray) {
// work the magic
}
and I really wanted to “work the magic”, even though “_ivarArray” previously also was an empty array.
October 28, 2011
В·
polesen В·
No Comments
Tags: objective-c В· Posted in: Programming

Leave a Reply