【问题标题】:Copy of an NSArray that doesn't do what I expected不符合我预期的 NSArray 的副本
【发布时间】:2023-03-13 08:05:01
【问题描述】:

我有一个 NSMutableArray,我将它传递给 tableViewController。用户将访问和更新数组中的数据。添加对象和删除对象。

为了能够在用户与之交互之前恢复到数组的状态,我想我会制作一个数组的副本。这样,如果用户决定取消而不继续,我可以将 copyArray 传回原始数组。

但是,当我在原始数组上更新一些数据时,它也会在副本数组上得到更新。

不,我没有将它们分配给彼此。我使用了以下代码。

array2 = [array1 copy];

我什至尝试过长篇大论的。

NSMutableArray *newArray = [[NSMutableArray alloc] initWithArray:oldArray copyItems:YES];

但如果我将 copyItems 设置为 YES,应用程序会因此错误而崩溃。

* 由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因:“-[SaleItem copyWithZone:]:无法识别的选择器已发送到实例 0xa21f3b0”

【问题讨论】:

  • 你试过 [[NSMutableArray alloc] initWithArray:oldArray] 吗?
  • [NSArray copy] 创建数组的浅表副本(即它不复制数组的内容,只是对旧对象进行新引用。您使用的第二种形式将尝试复制内容使用copycopyWithZone 对数组进行复制,它们都是NSCopying 协议的一部分。如果您想要数组的深层副本,则必须为每个内容类实现这些。
  • 您的 SaleItem 类不知道如何复制自己。您需要使其符合NSCopying 协议。

标签: ios objective-c arrays


【解决方案1】:

制作NSArray 的“副本”(或init从旧数组创建新数组)只会给您一个新数组,其中包含指向与第一个数组相同的对象的指针,而不是那些的副本对象。基于an answer to another question on Stack Overflow,您可以使用:

NSMutableArray *newArray = [[NSMutableArray alloc] initWithArray:oldArray copyItems:YES];

复制第一级项目(假设它们实现了NSCopying),尽管这可能足以满足您的目的,也可能不足以满足您的目的,具体取决于这些对象是什么。 That question I linked to 有更多关于制作 NSArray 的“深层”副本的答案。

【讨论】:

    【解决方案2】:

    您应该查看数组的深拷贝和浅拷贝之间的区别。简而言之,您只想要数据结构的副本,还是也想要数组中项目的副本? (原件和副本应该指向同一个对象吗?)

    要解决此错误:

    • 由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因:“-[SaleItem copyWithZone:]:无法识别的选择器已发送到实例 0xa21f3b0”

    您还需要在 SaleItem 类中使用 implement NSCopying

    【讨论】:

    • SalesItems 中有一个子类也需要实现 NSCopying。感谢@Isaac 和 Aaron,他们让我朝着正确的方向前进。
    猜你喜欢
    • 1970-01-01
    • 2013-12-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-11
    相关资源
    最近更新 更多