【问题标题】:NSMutableArray and pointer: an operation on the pointer is an operation on the original array (?)NSMutableArray 和指针:对指针的操作是对原始数组的操作(?)
【发布时间】:2011-09-07 10:33:55
【问题描述】:

要问一个简单的问题还有很长的路要走,但鉴于 Objective-C 中的指针对某些人来说是多么令人困惑,也许验证这里发生的事情会帮助其他人,以及我自己。

所以,简而言之,我有一个 UITableView,您可以在其中启用编辑和删除行。我想从表视图和数据源中删除该行。原始数据源位于模型类中,但我有一个指针/属性,其中包含本地表视图控制器中的数据。当我通过编辑从表格视图中删除一行时,它似乎可以工作并删除数据......但我不明白为什么。我认为这是因为我对指针的根本误解。

在我的带有 NSMutableArray 的模型类中:

@property (nonatomic,retain) NSMutableArray *allAlarms;
// ... plist gets read and serialized to an array ...
allAlarms = [NSMutableArray arrayWithArray:[plistValues objectForKey:@"Alarms"]];

在 UITableViewController 类中,我在 viewWillAppear 期间通过属性将可变数组拉入:

@property (nonatomic, retain) NSMutableArray *alarms;

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    // retrieve values from data controller
    self.alarms = [dataController returnAllAlarms];
    [self.tableView reloadData];
}

当执行编辑的委托方法时,我这样做了,它可以工作......

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete) {
    // Delete the row from the local data source
    [self.alarms removeObjectAtIndex:indexPath.row]; 
    // The above line appears to delete it in the local pointer as well as in the original property in the model class
    // so I just have to tell the data controller to save plist for when it's read back in via viewWillAppear
    [dataController writePlist];
    // Delete the row from the table view
    [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
}   

}

为什么我的 tableView:commitEditingStyle:forRowAtIndexPath 中发生的事情最终会起作用?在我的本地类中从指向 NSMutableArray 的指针中删除一项是否也会在远程类的原始指针中删除它,因为前者是指向后者的指针?

我需要了解,因为我将在此本地指针上执行其他操作,并希望确保我不会因为想要在远程属性上执行它而变得多余,等等。有什么关于我的'我在做不直观和多余的事情,还是在我继续学习 Objective-C 并更多地使用指针时它会更有意义?

【问题讨论】:

    标签: ios uitableview pointers nsmutablearray datasource


    【解决方案1】:

    是的,听起来您不太了解指针的工作原理。我不会试图自己解释这一切,而是将您指向这个thorough chapter on pointers

    需要注意的一点是,在 Objective-C 中,您永远不会在堆栈上分配对象1。对象总是在堆上分配,并返回一个指针给你。 (如malloc()。)这就是为什么在对象类型中总是有一个星号(*2。您的模型和控制器都有指向同一个底层数组的指针。 self.alarms = [dataController allAlarms] 不复制数组,它复制指针3

    当您调用 removeObjectAtIndex: 时,它不会改变指针的任何内容——指针只是一个数字——它取消引用指针并操作内存中的底层对象。

    1. 除了一个小例外,Blocks。
    2. 不包括 id,即 typedef'ed。
    3.如果您确实想要复制数组,请使用(copy) 属性属性而不是(retain)

    【讨论】:

    • 感谢您的参考(我会阅读它),但尽管阅读了所有教科书,但我还是误解了指针,所以我想我只是潜入并尝试。但我想我(基本上,有点)明白你在说什么:所以这两个指针都只是引用同一个数组。通过创建指向指针的指针,我只是在引用同一个数组。任何一个指针上的 removeObjectAtIndex 都会从同一个数组中删除对象。使用保留只是说“给我内存中同一个对象的所有权”。我在正确的轨道上吗?
    • 是的,你明白了。只是对术语的一些更正:当您设置self.alarms 时,这不是指向指针的指针。它是指针的副本。 (指向指针的指针看起来像NSError **)或者另一种思考方式,它是一个数字的副本。当你将一个 int 分配给一个 int 时,也会发生同样的事情。 (int i = 5, j = 3; j = i;) 如果您使用ij 作为数组索引,将j 设置为i 不会将array[3] 设置为array[5]。它只是改变了j 的值。回到指针,ints 是您的指针,array 是所有内存。
    • 这开始有意义了。非常感谢您的帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-11
    • 2011-01-18
    • 1970-01-01
    • 1970-01-01
    • 2017-11-06
    相关资源
    最近更新 更多