问题
I created an empty iOS app on Xcode 4.4.1, and did the following:
NSNumber *n1 = @1;
NSNumber *n2 = @2;
NSNumber *n3 = @3;
NSNumber *n100 = @100;
NSString *s = @"haha";
NSArray *a = @[n1, s];
NSDictionary *d = @{ @"ha" : @1, @3 : @"hello" };
NSLog(@"retain count of @1 is %i", [n1 retainCount]);
NSLog(@"retain count of @2 is %i", [n2 retainCount]);
NSLog(@"retain count of @3 is %i", [n3 retainCount]);
NSLog(@"retain count of @100 is %i", [n100 retainCount]);
NSLog(@"retain count of @\"haha\" is %i", [s retainCount]);
NSLog(@"retain count of array literal is %i", [a retainCount]);
NSLog(@"retain count of dictionary literal is %i", [d retainCount]);
and the result is:
retain count of @1 is 10
retain count of @2 is 4
retain count of @3 is 5
retain count of @100 is 1
retain count of @"haha" is -1
retain count of array literal is 1
retain count of dictionary literal is 1
so the retain count of array literal and dictionary literal is 1, and string literal is said to exist for the whole app's running, so that's why it is -1 (probably meaning MAX unsigned int), but the retain count of @1
actually come out as 7, 8, and 10 at different times. Is there a rule to it? I found that I can do [n1 retain]
and [n1 release]
as well, and it will increase and decrease the retain count accordingly.
回答1:
I don't know.
Neither does anybody on StackOverflow exactly.
Why?
Because it's only Apple's engineers who know it. Foundation is simple only in its interface - the underlying implementation is a mess. It's intermixed with the Objective-C runtime, optimized hard for a lot of possible or likely circumstances, and if something is mentioned in the docs as a thing that is not to be relied upon, that is to be taken seriously.
- retainCount
is one of them. It's not there to get the actual reference count of a particual instance of a class - its absolute value is meaningless. Only relative changes are meaningful in the case of this method. The use of autorelease pools and automatic reference counting (though not applicable here) add another level of ambiguity.
That's why.
Oh, and yes, do check out http://whentouseretaincount.com
回答2:
I think this points to the reason why: every time @1
is encountered, it is something like [[[NSNumber alloc] initWithInt:1] autorelease]
, and it appears that it returns the same object. So when the following is done:
NSMutableArray *arr = [[NSMutableArray alloc] init];
for (int i = 0; i < 300; i++) {
[arr addObject:@1];
}
the retain count actually becomes 610. And it is the same if the following is done:
NSMutableArray *arr = [[NSMutableArray alloc] init];
for (int i = 0; i < 300; i++) {
[arr addObject:[[[NSNumber alloc] initWithInt:1] autorelease]];
}
(Update: it is 610, because the retain count is increased by 1 by the usage of @1
, and another time when it is retained by the array, so it is 600 times total). It suggests that any usage of @1
any where will increase the retain count, and this NSNumber object is probably placed in the autorelease pool the same equal number of times.
来源:https://stackoverflow.com/questions/12418230/why-is-the-retain-count-of-1-equal-to-7-8-or-10