在iOS開發當中,如果是從C/C++轉過來的開發人員一定得注意,obj-c中的autorelease變量作用域問題。
如有www.2cto.com下面一個類;
@interface ViewController : UIViewController
{
NSDate *memberDate;
NSDate *properDate;
}
@property(nonatomic, retain) NSDate* properDate;
@end
@interface ViewController : UIViewController
{
NSDate *memberDate;
NSDate *properDate;
}
@property(nonatomic, retain) NSDate* properDate;
@end
然後在類實現中對其成員變量初始化:
- (void)viewDidLoad
{
[super viewDidLoad];
memberDate = [NSDate date];
self.properDate = [NSDate date];
}
- (void)viewDidLoad
{
[super viewDidLoad];
memberDate = [NSDate date];
self.properDate = [NSDate date];
}
然後在類的成員方法中用使用這兩個成員變量,如[memberDate description]。這時候memberDate的值是無效的,而properDate的值是有效的。為什麼會這樣呢?
因為memberDate = [NSDate date];這句執行後,memberDate指向的是一個autorelease的變量,這些autorelease的變量在runloop下一次輪詢的時候會被release。所以memberDate就是c/c++中的野指針,野指針會讓程序crash掉。而property是用retain聲明的屬性,所以成員變量properDate指向的地址retrain count是1,不會被auto release,所以是有效的內存空間,當然就不會crash了。
得出的教訓:autorelease變量最好在其作用域內使用,除非你手動retrain,如上面代碼可改變memberDate = [[NSDate date] retrain];這樣memberDate指向的地址就與類的生命周期一樣,retrain count為1,不會被autorelease。但是在dealloc方法裡一定要手動[memberDate release]不然就有內存溢出。
摘自 開心程序