These rules apply only if you use manual reference counting!
You own any object you create
By calling a method whose name begins with alloc
, new
, copy
or mutableCopy
.
For example:
NSObject *object1 = [[NSObject alloc] init];
NSObject *object2 = [NSObject new];
NSObject *object3 = [object2 copy];
That means that you are responsible for releasing these objects when you are done with them.
You can take ownership of an object using retain
To take ownership for an object you call the retain method.
For example:
NSObject *object = [NSObject new]; // object already has a retain count of 1
[object retain]; // retain count is now 2
This makes only sense in some rare situations.
For example when you implement an accessor or an init method to take ownership:
- (void)setStringValue:(NSString *)stringValue {
[_privateStringValue release]; // Release the old value, you no longer need it
[stringValue retain]; // You make sure that this object does not get deallocated outside of your scope.
_privateStringValue = stringValue;
}
When you no longer need it, you must relinquish ownership of an object you own
NSObject* object = [NSObject new]; // The retain count is now 1
[object performAction1]; // Now we are done with the object
[object release]; // Release the object
You must not relinquish ownership of an object you do not own
That means when you didn't take ownership of an object you don't release it.
Autoreleasepool
The autoreleasepool is a block of code that releases every object in the block that received an autorelease message.
Example:
@autoreleasepool {
NSString* string = [NSString stringWithString:@"We don't own this object"];
}
We have created a string without taking ownership. The NSString
method stringWithString:
has to make sure that the string is correctly deallocated after it is no longer needed. Before the method returns the newly created string calls the autorelease method so it does not have to take ownership of the string.
This is how the stringWithString:
is implemented:
+ (NSString *)stringWithString:(NSString *)string {
NSString *createdString = [[NSString alloc] initWithString:string];
[createdString autorelease];
return createdString;
}
It is necessary to use autoreleasepool blocks because you sometimes have objects that you don't own (the fourth rules does not always apply).
Automatic reference counting takes automatically care of the rules so you don't have to.