【问题标题】:NSMutableArray accessor returning NSArrayNSMutableArray 访问器返回 NSArray
【发布时间】:2012-08-23 04:09:45
【问题描述】:

我有一个 NSMutableArray

@property (copy, nonatomic) NSMutableArray *childrenArray;

现在我像这样初始化它:

self.childrenArray = [NSMutableArray arrayWithArray:children];

上面的children也是nsmutable的,

现在,当我从子数组中删除一个对象时,我收到了这个错误:

[__NSArrayI removeObjectAtIndex:]: unrecognized selector sent

我立即明白我的 remove 正在 NSArray 上被调用,所以我的问题是为什么我的访问器返回 NSArray,因为它应该返回 NSMutableArray。

谢谢,

【问题讨论】:

    标签: iphone objective-c nsmutablearray


    【解决方案1】:

    首先,copy @property 从字面上将copy 发送到正在设置的对象。可变集合通过创建不可变副本来响应copy。可变复制充斥着边缘情况(其中许多已在其他 SO 问题中讨论过)。

    其次,您真的真的不希望属性提供对对象内可变状态的访问。而且您可能不想出售可变集合类。


    直言:

    copy 发送到可变集合会返回一个不可变副本。 copy 属性不会保留可变性。

    手动实现 setter/getter 来设置/返回可变实例可能是错误的。


    这样想:

    您有一个名为“Person”的类,它有一个名为“firstName”的属性。如果该属性是可变的,有人可能会说:

     [[aPerson firstName] setString:@"Joe"];
    

    即您是否希望某人能够在没有任何通知的情况下更改您的名字?可能不是。但这正是通过在可变容器中公开对象的状态所允许的。

    【讨论】:

    • 您好,谢谢,对不起,我没能找到您,您能不能更简单地解释一下,如果复制有问题,我应该使用保留吗?
    • 嗨,一遍又一遍地阅读您的答案后,我的理解是:首先我没有手动实现 setter 和 getter,synthesize 正在做所有事情,所以这意味着当我用 setter 初始化我的可变数组时它调用复制并且复制不保留可变性,因此访问器返回不可变。其次,所以我需要直接在 member 上初始化,而不是像这样 childrenArray = [[NSMutableArray arrayWithArray:children] retain]; (如果我仍然错了,请纠正我)。谢谢
    • 我也认为我应该使用保留语义而不是复制,因为复制返回不可变。谢谢。
    • retain 可以,是的,但是——总的来说——你不想将可变集合从 inside 实例暴露给外部世界。它破坏了封装。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多