我的iPhone應用程序(在UINavigationController中)的UIViewController中有一個方法,只要在ViewController的視圖中的表中選擇一行即可調用該方法。在此方法中,我訪問存儲在實例字段dreamsArray中的「Dream」數組,該數組包含來自我的數據庫的NSManagedObjects。我可以在其他方法中訪問此數組中的對象,但似乎每當我嘗試從此數組中檢索或修改檢索到的對象時,程序都會崩潰。每當在某個方法中訪問NSManagedObjects時,應用程序崩潰
這裏是dreamsArray是如何創建的:
dreamsArray = [[NSMutableArray alloc] init];
[self managedObjectContext];
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Dream" inManagedObjectContext:managedObjectContext];
[request setEntity:entity];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"title" ascending:NO];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
[request setSortDescriptors:sortDescriptors];
[sortDescriptors release]; [sortDescriptor release];
NSError *error;
NSMutableArray *mutableFetchResults = [[managedObjectContext executeFetchRequest:request error:&error] mutableCopy];
if (mutableFetchResults == nil)
NSLog(@"oh noes! no fetch results DreamsTabController:45");
dreamsArray = [mutableFetchResults mutableCopy];
[mutableFetchResults release];
[request release];
的實例中查詢dreamsArray及其對象的工作原理:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *cellID = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellID];
if (cell == nil)
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellID] autorelease];
Dream *dream = (Dream *)[dreamsArray objectAtIndex:indexPath.row];
cell.textLabel.text = [dream title];
cell.detailTextLabel.text = @"foo!";
[dream release];
return cell;
}
而且具有所有問題的方法:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
Dream *dream = (Dream *)[dreamsArray objectAtIndex:indexPath.row];
// BOOM - crashes right here
EditDreamController *edit = [[EditDreamController alloc] initWithNibName:@"EditDream" bundle:nil];
edit.dream = [[NSArray alloc] initWithObjects:dream.dreamContent, nil];
[navigationController pushViewController:edit animated:YES];
[dream release];
[edit release];
}
這個應用程序在dreamsArray被查詢後立即崩潰。
即使在此方法中調用簡單的NSLog(@"%@", dream.title)
也會導致崩潰。這裏可能會出現什麼問題?
小問題:我個人會使用[[fetchResults mutableCopy] autorelease]而不是[NSMutableArray arrayWithArray:fetchResults],因爲理論上fetchResults可以有一個優化的mutableCopy方法(將來,即使目前沒有)。 –
我永遠不會使用-mutableCopy,因爲我只是不相信它。其中一個原因是,我幾乎不記得'mutableCopy'是否很深(不應該),如果我不記得,我怎麼能期待其他人閱讀我的代碼來記住? 另一個是因爲如果它以這種方式優化,那麼使用它來快速枚舉安全(因爲我正在修改基本數組)仍然是不安全的。 另外,如果基本數組是一個不可思議的NSArray子類,現在我知道這只是一個正常的。 –
您不記得它是否是深層副本的說法很弱,因爲您可以對arrayWithArray說同樣的話。如果你不能輕易記住某些東西,你就不應該這樣做(例如,我忘記了&&和||之間的優先順序,所以我使用了括號)。我個人並不認爲記得mutableCopy是否有深度拷貝屬於這個類別;這是你應該知道的。 –