TL;DR The way you are logging can affect the results, you might get a temporary ownership when logging, therefore increasing all your printing results by 1.
The following answer is a simplification because you shouldn't really worry about the real value in retainCount
.
The retain count keeps a count how many references (owners) the given object has.
When created, there is exactly one owner, therefore the retain count is set to 1. Every time the object gets a new owner (retain
), the retain count is increased by one. Every time the object loses and owner (release
) the retain count is decreased by one.
Note that the retainCount
can never reach zero. If the number of owners is 1 and you lose the owner, the object is deallocated, the count is not decreased then.
For a better test, I have created an Obj-C class, compiled without ARC:
@implementation TestObject
- (instancetype)init {
TestObject *result = [super init];
NSLog(@"Retain count after creation: %@", @(self.retainCount));
return result;
}
- (instancetype)retain {
TestObject *result = [super retain];
NSLog(@"Retain count after retain: %@", @(self.retainCount));
return result;
}
- (oneway void)release {
NSLog(@"Retain count before release: %@", @(self.retainCount));
[super release];
}
- (void)dealloc {
NSLog(@"Retain count before dealloc: %@", @(self.retainCount));
[super dealloc];
}
@end
and used it in Swift instead of your NSObject
:
var foo1: TestObject? = TestObject()
print("#")
print(CFGetRetainCount(foo1))
var foo2 = foo1
print("#")
print(CFGetRetainCount(foo1))
foo2 = nil
print("#")
print(CFGetRetainCount(foo1))
foo1 = nil
Resulting in:
Retain count after creation: 1
#
Retain count after retain: 2
2
Retain count before release: 2
Retain count after retain: 2
#
Retain count after retain: 3
3
Retain count before release: 3
Retain count before release: 2
#
Retain count after retain: 2
2
Retain count before release: 2
Retain count before release: 1
Retain count before dealloc: 1
Which is basically what you would expect but there are additional retains and releases around every CFGetRetainCount
when you get a temporary ownership when passing the object into the function.
This is one of the examples why you should never read the value of retainCount
. It has no debugging value, which is also mentioned in the documentation.