2012年5月27日 星期日

Reference Counting in autorelease and dealloc

refer to  Addison Wesley - Programming.in.ObjectiveC.2.0.2nd (2009)

@interface ClassA: NSObject
{
NSString *str;
}
-(void) setStr: (NSString *) s;
-(NSString *) str;
-(void) dealloc;
@end

@implementation ClassA
-(void) setStr: (NSString *) s
{
// free up old object since we ’ re done with it
[str autorelease];
// retain argument in case someone else releases it
str = [s retain];
}
-(NSString *) str
{
return str;
}
-(void) dealloc {  //重新定義dealloc
NSLog (@ ” ClassA dealloc ” );
[str release];
[super dealloc];
}
@end
int main (int argc, char *argv[])
{
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
NSString  *myStr = [NSMutableString stringWithString: @ ” A string ” ];

ClassA  *myA = [[ClassA alloc] init];
NSLog (@ ” myStr retain count: %x ” , [myStr retainCount]);
[myA autorelease];

[myA setStr: myStr];
NSLog (@ ” myStr retain count: %x ” , [myStr retainCount]);

[pool drain]; // autorelease 過程中會去叫到dealloc
return 0;
}

myStr retain count: 1
myStr retain count: 2
ClassA dealloc

當該物件的retain count降到0的時候,這個物件自動會呼叫dealloc方法把自己解決掉,然後把佔用的記憶體還回來。

Another Case

@interface Foo: NSObject
{
int x;
}
@end
 
@implementation Foo
@end
 
int main (int argc, char *argv[])
{
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
Foo   *myFoo = [[Foo alloc] init];

NSLog (@ ” myFoo retain count = %x ” , [myFoo retainCount]);
 
[pool drain]; //真正執行動作是在程式結束之後
NSLog (@ ” after pool release  = %x ” , [myFoo retainCount]);
 
pool = [[NSAutoreleasePool alloc] init];
[myFoo autorelease]; //真正執行動作是在程式結束之後
NSLog (@ ” after autorelease = %x ” , [myFoo retainCount]);
 
[myFoo retain];
NSLog (@ ” after retain = %x ” , [myFoo retainCount]);
  
[pool drain];  // 之前已經有autorelease, 因此會先release一次
NSLog (@ ” after second pool drain = %x ” , [myFoo retainCount]);
 
[myFoo release];
return 0;
}

myFoo retain count = 1
after poolrelease = 1
after autorelease = 1
after retain = 2
after second pool drain = 1
 

沒有留言: