2010-10-08 63 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

相关问题