2010-10-08 64 views
2

我有一個正常工作的導航應用程序。在表格視圖中,最後一個項目被稱爲「添加項目」,如果用戶按下它,它會創建一個新對象並將其傳遞到另一個視圖,在該視圖中用戶可以輸入該對象的詳細信息。當用戶返回到前一個屏幕時,新對象將顯示在表中顯示的數組中。編輯NSMutableArray中的一個對象也會更改NSMutableArray中的另一個對象

我改變了它,以便「add item」字段始終是表中的第一個字段,而不是最後一個。我做了適當的更改,以便數組在桌面上正確顯示。但是,現在我注意到奇怪的行爲。

如果我編輯數組中的第一個對象,則第7個對象也會變爲與此對象相同。如果我編輯數組中的第二個對象,則第四個和第六個對象也會更改爲相同。如果我編輯數組中的第三項,則第五個對象將變爲相同。

會發生什麼情況?

在viewDidLoad中:方法我初始化對象是這樣的:

PersonDetails *personDetails = [[PersonDetails alloc] init]; 

這是當一個用戶對錶

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 
// Navigation logic may go here. Create and push another view controller. 
updatePersonArray = YES; 
arrayIndex = indexPath.row-1;  
editPerson = [[EditClassController alloc] initWithNibName:@"EditPerson" bundle:nil];  
editPerson.title = @"Edit Person"; 

if (arrayIndex != -1) { 
    personDetails = [classArray objectAtIndex:arrayIndex];  
} 
else { 
    personDetails = [[PersonDetails alloc] init]; 
} 
editPerson.personDetails = personDetails; 

[self.navigationController pushViewController:editPerson animated:YES]; 
[editPerson release]; 

}

選擇的行被執行的方法

這是viewWillAppear的樣子。它將在對象編輯後更新表格。

- (void)viewWillAppear:(BOOL)animated { 
    [super viewWillAppear:animated]; 

    if ([personDetails isEmpty]) { 
     updatePersonArray = NO; 
    } 

    if (updatePersonArray) { 
     if (arrayIndex == -1) { 
      NSLog(@"adding new object to array"); 
      [personArray addObject:personDetails]; 
     } 
     else { 
      NSLog(@"replacing object at index %d", arrayIndex); 
      [personArray replaceObjectAtIndex:arrayIndex withObject:personDetails]; 
      } 

     [self saveArrayToDisk]; 

     [self.tableView reloadData]; 

     updatePersonArray = NO; 
    } 
    else { 
     //load the array from disk 
    NSLog(@"loading array from disk"); 
     NSData *theData = [[NSUserDefaults standardUserDefaults] objectForKey:@"personArray"]; 
     if (theData != nil) { 
      NSLog(@"found something"); 
      personArray = [[NSMutableArray alloc] initWithArray:[NSKeyedUnarchiver unarchiveObjectWithData:theData]]; 
     } 
     else { 
      personArray = [[NSMutableArray alloc] init]; 
     } 

    } 

} 

編輯:我解決由從陣列實施NSCopy用於人對象,然後使對象的副本,而不是直接指向陣列中的對象的問題。任何人都知道爲什麼這解決了問題?

+0

也許你可以顯示一些代碼?聽起來就像你沒有創建對象,而是引用數組中的同一個對象。 – 2010-10-08 08:43:04

+0

我在數組中創建了對象的副本並解決了問題。 – 2010-10-08 12:43:47

回答

3

編輯:我通過 實施NSCopy的人 對象,然後使解決問題直接指向 數組中的對象的 對象的副本,而不是 。任何人都知道爲什麼這解決了 問題?

原始問題幾乎保證是多次在數組中具有相同PersonDetails的問題。如果你要做這樣的事情:

for (id p in myArray) NSLog("%p", p); 

我敢打賭,一些地址將是相同的,多次指示相同的對象在數組中。

這就是爲什麼複製對象「固定」的問題。您通過複製每一次插入來隱藏導致上述情況的詭計邏輯。

1

這部分在這裏看起來有點躲閃對於內存的所有權:

if (arrayIndex != -1) { 
    // here you get back an autorelease object - which you haven't retained 
    personDetails = [classArray objectAtIndex:arrayIndex]; 
} 
else { 
    // here you create an object with retainCount =1 
    personDetails = [[PersonDetails alloc] init]; 
} 

// depending on your property attribute this may or may not work as you expect 
editPerson.personDetails = personDetails; 

@property(??) personDetails

+0

在h文件中,我擁有@property(nonatomic,retain)PersonDetails * personDetails,然後我將它合成到m文件中。 – 2010-10-08 10:02:53

+0

好,所以你得到一個泄漏,然後在上面的代碼personDetails = [[PersonDetails的]初始化](不是你的問題可以幫助你) – 2010-10-08 10:19:47

+0

你指的是哪個實例?你在說didSelectRowAtIndexPath中的那個嗎?這是因爲用戶將添加新對象,因此必須創建新對象。 – 2010-10-08 11:42:42

相關問題