retain Count NSArray vs. NSMutableArray
Short Question with a code ex开发者_如何学Cample:
NSLog(@"%i", [[[NSArray alloc] init] retainCount]);
NSLog(@"%i", [[[NSMutableArray alloc] init] retainCount]);
Output:
2
1
Why is the retainCount from the NSArray and NSMutableArray different?
Nobody outside of apple knows for sure (but I'm sure soon there will be somebody that claims he knows exactly why that happened).
Maybe this happens because iOS is smart and it reuses empty NSArrays. And obviously [[NSArray alloc] init]
creates an empty array that is of no real use. And since it`s not mutable (ie you can't add objects later, and it will be empty forever) all empty NSArrays pointers can reference the same object.
The mutable one can't be reused because you can add objects to it.
Do not use retainCount!
From the apple documentation:
Important: This method is typically of no value in debugging memory management issues. Because any number of framework objects may have retained an object in order to hold references to it, while at the same time autorelease pools may be holding any number of deferred releases on an object, it is very unlikely that you can get useful information from this method.
To understand the fundamental rules of memory management that you must abide by, read “Memory Management Rules”. To diagnose memory management problems, use a suitable tool:
- The LLVM/Clang Static analyzer can typically find memory management problems even before you run your program.
- The Object Alloc instrument in the Instruments application (see Instruments User Guide) can track object allocation and destruction.
- Shark (see Shark User Guide) also profiles memory allocations (amongst numerous other aspects of your program).
The reason is that [[NSArray alloc] init] returns the same object no matter how many times you call it. Look at this code:
NSArray *array1 = [[NSArray alloc] init];
NSArray *array2 = [[NSArray alloc] init];
NSArray *array3 = [[NSArray alloc] init];
NSLog(@"\narray1: %p\narray2: %p\narray3: %p",
array1, array2, array3);
The output is:
array1: 0x10010cae0
array2: 0x10010cae0
array3: 0x10010cae0
This makes sense, because NSArray is immutable, and all empty arrays are identical. It looks like NSArray keeps an empty array handy for this purpose since the retain count for the array pointed to by array1, array2, and array3 is 4.
I don't disagree with @fluchtpunkt's answer, but I think it's safe to say that we know exactly why this happens. I suppose you could say that nobody knows exactly why Apple chose to implement it this way, but it does seem like a good idea.
精彩评论