2012年11月13日 星期二

iOS學習_返回NSMutableArray的函式要正確release的方法(ola的猜測)

本文章為筆者自行觀念的瞭解,無法保證一定正確。 ------------------------------------------- NSMutableArray是一個非常好用的型態,我們可以將他看作一個物件陣列(操作方法),慢慢的我們會將處理NSMutableArray獨立出一個一個方法,類似下面的程式碼:
-(NSMutableArray *)selectReportingMain_All
而函式的內容不外乎alloc一個NSMutableArray,然後將適當的物件放進去,在return NSMutableArray:
-(NSMutableArray *)selectReportingMain_All { NSMutableArray *items = [[NSMutableArray alloc] init]; if ([db open]) { FMResultSet *rs = [db executeQuery:@"SELECT * From reportingMain"]; while ([rs next]) { NSString *reportingID = [rs stringForColumn:@"reportingID"]; NSString *title = [rs stringForColumn:@"title"]; NSString *note = [rs stringForColumn:@"note"]; NSString *xValue = [rs stringForColumn:@"xValue"]; NSString *yValue = [rs stringForColumn:@"yValue"]; NSString *time = [rs stringForColumn:@"time"]; NSString *status = [rs stringForColumn:@"status"]; [items addObject:[NSDictionary dictionaryWithObjectsAndKeys: reportingID , @"reportingID", title , @"title", note , @"note", xValue , @"xValue", yValue , @"yValue", time , @"time", status , @"status", nil]]; } } [db close]; return items; }
上述程式碼為SQLite查詢的操作,這樣就可以簡單的將資料庫操作與界面做一個簡單的切割,但是觀察上面的程式碼可能會覺得有點詭異?
我們並沒有釋放items,難道每一次地使用就會不斷佔用記憶體嗎?這豈不是慢性自殺?

所以必須在適當的時機點進行釋放,所謂適當的時機就是“立刻”。 return [items autorelease];
如此,我們即可確保該NSMutableArray有被進行釋放。但通常會去接這一個NSMutableArray的介面都會準備一個全域變數,來承接吐出來的結果。
dbOperating *dbO = [[dbOperating alloc] init]; itembag = [dbO selectReportingMain_All]; NSLog(@"items retain:%d",items.retainCount); [dbO release]; 上述程式碼itembag可以很順利地取得結果,但是當該介面的其他函示需要進行操作時,則會產生“exc_bad_access”的錯誤,也就是說你使用了已經釋放的變數。

解決方法: dbOperating *dbO = [[dbOperating alloc] init]; itembag = [dbO selectReportingMain_All]; [itembag retain]; NSLog(@"items retain:%d",items.retainCount); [dbO release]; 手動增加itembag的retainCount,這時如果將retainCount輸出,會看到在上述程式碼內retainCount為2,但因回傳的變數是使用[items autorelease],所以隨即retainCount會降為1,並且也可以正常的讀取使用itembag裡面的值。

沒有留言:

張貼留言