Stupid question, but why do we need to use 'retain' when declaring a property? Doesn't it get retained anyway when it's assigned something?
Looking at this example, it seems that an object is automatically re开发者_运维技巧tained when alloc'ed, so what's the point?
#import "Fraction.h"
#import <stdio.h>
int main( int argc, const char *argv[] ) {
Fraction *frac1 = [[Fraction alloc] init];
Fraction *frac2 = [[Fraction alloc] init];
// print current counts
printf( "Fraction 1 retain count: %i\n", [frac1 retainCount] );
printf( "Fraction 2 retain count: %i\n", [frac2 retainCount] );
// increment them
[frac1 retain]; // 2
[frac1 retain]; // 3
[frac2 retain]; // 2
// print current counts
printf( "Fraction 1 retain count: %i\n", [frac1 retainCount] );
printf( "Fraction 2 retain count: %i\n", [frac2 retainCount] );
// decrement
[frac1 release]; // 2
[frac2 release]; // 1
// print current counts
printf( "Fraction 1 retain count: %i\n", [frac1 retainCount] );
printf( "Fraction 2 retain count: %i\n", [frac2 retainCount] );
// release them until they dealloc themselves
[frac1 release]; // 1
[frac1 release]; // 0
[frac2 release]; // 0
■output
Fraction 1 retain count: 1
Fraction 2 retain count: 1
Fraction 1 retain count: 3
Fraction 2 retain count: 2
Fraction 1 retain count: 2
Fraction 2 retain count: 1
Deallocing fraction
Deallocing fraction
This is driving me crazy!
The default behavior of a property is ASSIGN, not RETAIN. These are not the same behavior. If your property is for a primitive data type, such as an int, then ASSIGN would be correct to use. However, if you specify (retain) and the property points to an object pointer such as NSObject *object, the pointer is assigned the memory address of the object and it's retain count is incremented by one. If your program consists of nothing more than a lone main function, then it's purpose is hard to see. However, suppose your class had this method:
-(void)setMyArrayWithString:(NSString *)s{
myArray = [NSArray arrayWithObject:s];
}
Suppose myArray is defined as NSArray *myArray and has the proper @property (retain) statement. Everything works fine until the method returns. This is because the object returned from NSArray is an autoreleased object. If we don't retain it, it will be released by the NSAutoReleasePool and we won't be able to use it (and we'll get nasty bugs and bad access violations). To fix this we can do one of two things:
-(void)setMyArrayWithString:(NSString *)s{
self.myArray = [NSArray arrayWithObject:s];
// OR
myArray = [[NSArray arrayWithObject:s] retain];
}
The first solution uses self.myArray to utilize the @property definition. This code assigns and then retains the object so that we don't lose it when the function returns. The second solution sets the NSArray *myArray pointer manually and then manually retains the NSArray object. Either way the NSAutoreleasePool will release the object at the end of the function, however it won't be deallocated because we still have our retain from earlier keeping it alive.
精彩评论