--前言:iOS開發中關於對象的釋放問題,雖然知道規則,但總不清楚自動釋放的對象什麼時候徹底消失?它存在的多久?什麼情況會消失?都不清楚,每次用自動釋放對象,總有點心虛的感覺,以下是一些例子、研究。
--直接上代碼,代碼寫在一個控制器的viewDidLoad方法裡(代碼內容是用一個path就保存一個data,但path是自動釋放對象):
[html]
例子1
NSArray*patharray=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString*docstr=[patharray objectAtIndex:0];
//path成員變量,文件路徑-自動釋放對象
path=[docstr stringByAppendingPathComponent:@"1.png"];
//data讀取內容
NSString *imagePath = [[NSBundle mainBundle] pathForResource:@"IMG_1340" ofType:@"PNG"];
NSData *data= [NSData dataWithContentsOfFile:imagePath];
//用path去保存data
[data writeToFile:path atomically:NO];
//例子1
NSArray*patharray=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString*docstr=[patharray objectAtIndex:0];
//path成員變量,文件路徑-自動釋放對象
path=[docstr stringByAppendingPathComponent:@"1.png"];
//data讀取內容
NSString *imagePath = [[NSBundle mainBundle] pathForResource:@"IMG_1340" ofType:@"PNG"];
NSData *data= [NSData dataWithContentsOfFile:imagePath];
//用path去保存data
[data writeToFile:path atomically:NO];例子1,這麼寫,沒問題,文件能保存。 [html] view plaincopyprint? //例子2
NSArray*patharray=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString*docstr=[patharray objectAtIndex:0];
//path成員變量,文件路徑-自動釋放對象
path=[docstr stringByAppendingPathComponent:@"1.png"];
//調用方法,path做參數
[self saveData:path];
//分割線
-(void)saveData:(NSString *)filePath
{
//data讀取內容
NSString *imagePath = [[NSBundle mainBundle] pathForResource:@"IMG_1340" ofType:@"PNG"];
NSData *data= [NSData dataWithContentsOfFile:imagePath];
//用path去保存data
[data writeToFile:filePath atomically:NO];
}
//例子2
NSArray*patharray=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString*docstr=[patharray objectAtIndex:0];
//path成員變量,文件路徑-自動釋放對象
path=[docstr stringByAppendingPathComponent:@"1.png"];
//調用方法,path做參數
[self saveData:path];
//分割線
-(void)saveData:(NSString *)filePath
{
//data讀取內容
NSString *imagePath = [[NSBundle mainBundle] pathForResource:@"IMG_1340" ofType:@"PNG"];
NSData *data= [NSData dataWithContentsOfFile:imagePath];
//用path去保存data
[data writeToFile:filePath atomically:NO];
} 例子2,這麼寫,也沒問題,文件能保存。或者[self saveData:path]; 改成[self saveData]; saveData方法不傳入參數,用成員變量path代替filePath的作用,這麼寫,也沒問題。[html] view plaincopyprint? //例子3
NSArray*patharray=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString*docstr=[patharray objectAtIndex:0];
//path成員變量,文件路徑-自動釋放對象
path=[docstr stringByAppendingPathComponent:@"1.png"];
//創建按鈕
UIButton *button = [[UIButton alloc]initWithFrame:CGRectMake(0.0, 0.0, 100, 100)];
button.backgroundColor = [UIColor redColor];
;
[self.view addSubview:button];
-(void)saveData
{
//data讀取內容
NSString *imagePath = [[NSBundle mainBundle] pathForResource:@"IMG_1340" ofType:@"PNG"];
NSData *data= [NSData dataWithContentsOfFile:imagePath];
//用path去保存data
[data writeToFile:path atomically:NO];
}
//例子3
NSArray*patharray=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString*docstr=[patharray objectAtIndex:0];
//path成員變量,文件路徑-自動釋放對象
path=[docstr stringByAppendingPathComponent:@"1.png"];
//創建按鈕
UIButton *button = [[UIButton alloc]initWithFrame:CGRectMake(0.0, 0.0, 100, 100)];
button.backgroundColor = [UIColor redColor];
;
[self.view addSubview:button];
-(void)saveData
{
//data讀取內容
NSString *imagePath = [[NSBundle mainBundle] pathForResource:@"IMG_1340" ofType:@"PNG"];
NSData *data= [NSData dataWithContentsOfFile:imagePath];
//用path去保存data
[data writeToFile:path atomically:NO];
}例子3,點擊button,程序會崩潰,提示“Thread 1:EXC_BAD_ACCESS(code =1, address = 0x0000008)” 。但如果將 path=[docstr stringByAppendingPathComponent:@"1.png"];改成path = [NSString stringWithString:[docstr stringByAppendingPathComponent:@"1.png"]];程序也行,不會崩潰。
--綜上看來,“系統返回的自動釋放對象”它的存在周期,在一個方法裡是有效的(例子1/2),但離開了這個方法,在別的方法,別的地方就不能使用了(例子3),同時“自己創建的自動釋放對”比“系統返回的自動釋放對象”存在周期長點(例子3改動),但也不是總是存在,有時候用著用著就沒了(曾經碰到過,一個自己創建的自動釋放的數組,程序運行久了,有時崩潰,就是用著用著該數組沒了)。
--總結,如果一個對象你要用,之前retain,用完了就release,這樣能確保自動釋放對象消息。(例子3中將 path=[docstr stringByAppendingPathComponent:@"1.png"]; 改為path = [NSString stringWithString:[docstr stringByAppendingPathComponent:@"1.png"]] 之後,程序正常運行)