为什么我必须制作这个数组的可变副本?

5
苹果提供了以下示例:
NSError *error;
NSMutableArray *mutableFetchResults = [[managedObjectContext executeFetchRequest:request error:&error] mutableCopy];
if (mutableFetchResults == nil) {
    // Handle the error
}

为什么他们在这里调用mutableCopy?是因为他们想要一个NSMutableArray而不是NSArray,以便稍后进行编辑/更改吗?还是有其他原因?

1
很难在没有看到其他代码的情况下回答。你尝试搜索使用mutableFetchResults的其他行了吗? - ewall
4个回答

6
在提供你示例的文章中可以找到答案:

当表视图控制器加载其视图时,它应该获取事件对象并将它们保存在事件数组中,以便稍后显示。 由于用户可能会添加和删除事件,因此事件数组需要是可变的。

你示例代码块是从持久存储中获取托管对象的多个步骤中的一部分。该过程的下一步将调用setEventsArray:,需要一个可变数组。

该过程的下一步将调用setEventsArray:,它需要一个可变数组。这很糟糕:任何获取eventsArray的东西都可以在其所有者不知情的情况下改变它。安全的做法是使数组属性公开不可变,类的访问器是唯一可以改变数组的方式。这个副本是必要的(将其移动到setEventsArray:中也不会更慢),如果确实有这样的优化,则可以削减getter中的副本(以返回可变数组的不可变副本)。 - Peter Hosey

3

如果我没记错的话,使用[myObject copy]默认会创建一个不可变的对象副本,因此如果你有NSMutableArray,它会变成NSArray。

因为在这个例子中你想要保持可变性和操作数组的能力,所以你调用[myObject mutableCopy];来确保你得到一个可变的对象副本。


2
这段示例代码可能来自于苹果文档中的“iPhone核心数据教程”。如果是这样,那么他们进行mutableCopy的原因是需要将NSMutableArray赋值给被定义为NSMutableArray的实例变量。示例代码将mutableFetchResults设置为实例变量,如下所示。
[self setEventsArray:mutableFetchResults];
[mutableFetchResults release];
[request release];

然后,实例变量的定义如下。
@interface RootViewController : UITableViewController <CLLocationManagerDelegate> {

    NSMutableArray *eventsArray;
    NSManagedObjectContext *managedObjectContext;

    CLLocationManager *locationManager;
    UIBarButtonItem *addButton;
}

0
很难在没有看到示例的情况下说出他们为什么这样做。唯一的原因是要创建一个可修改的数组副本。但是,如果你只是想读取获取的项目,那么没有必要创建一个可变或不可变的副本。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接