Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/iphone/44.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Iphone 什么';将Obj-C2.0属性用于可变对象(如NSMutableArray)的最佳方法是什么?_Iphone_Objective C_Cocoa_Macos_Properties - Fatal编程技术网

Iphone 什么';将Obj-C2.0属性用于可变对象(如NSMutableArray)的最佳方法是什么?

Iphone 什么';将Obj-C2.0属性用于可变对象(如NSMutableArray)的最佳方法是什么?,iphone,objective-c,cocoa,macos,properties,Iphone,Objective C,Cocoa,Macos,Properties,我有一个Obj-C2.0类,它具有NSMutableArray属性。如果我使用以下代码,那么综合setter将给我一个不可变的副本,而不是可变的副本: @property (readwrite, copy) NSMutableArray *myArray; 苹果没有实现以下语法有什么原因吗 @property (readwrite, mutablecopy) NSMutableArray *myArray; 既然我们没有mutablecopy,那么处理这种(看似常见的)情况的最佳方法是什么?

我有一个Obj-C2.0类,它具有NSMutableArray属性。如果我使用以下代码,那么综合setter将给我一个不可变的副本,而不是可变的副本:

@property (readwrite, copy) NSMutableArray *myArray;
苹果没有实现以下语法有什么原因吗

@property (readwrite, mutablecopy) NSMutableArray *myArray;

既然我们没有
mutablecopy
,那么处理这种(看似常见的)情况的最佳方法是什么?我是否应该编写自己的setter来执行-mutableCopy?

您必须编写自己的setter。

我不久前遇到了同样的问题,并找到了一个建议,建议您提供自己的setter实现。链接文档的代码示例表单:

@interface MyClass : NSObject {
    NSMutableArray *myArray;
}
@property (nonatomic, copy) NSMutableArray *myArray;
@end

@implementation MyClass

@synthesize myArray;

- (void)setMyArray:(NSMutableArray *)newArray {
    if (myArray != newArray) {
        [myArray release];
        myArray = [newArray mutableCopy];
    }
}

请记住,传递可变数组在Cocoa中并不常见。您可以使用私有可变数组作为内部存储,但可以使用普通NSArray对象创建方法来添加对象或从中获取对象。这可能就是为什么没有mutablecopy属性声明。

在Cocoa中传递
NSMutableArray
s并不常见。标准的Cocoa实践是为索引到多个属性实现符合键值的编码。这有两个好处:

  • 键值观察按预期工作(有几种情况下,观察NSMutableArray会导致您不想要的行为)
  • 数据结构的实现是隐藏的,因为您公开了变异方法(例如,
    -[MyObject insertObjectInMyProperty:(id)newObject atIndex:(nsInteger)i]
    ,而不是数据结构本身

  • 如前所述,正确的方法不是将可变数组设为属性。这里有一个很好的解释,说明了您应该实现什么以符合KVC。

    保持NSMutableArray的正确方法是使用retain属性:

    @property (nonatomic, retain) NSMutableArray *myArray;
    
    您不需要编写自己的setter或使用copy。copy属性应与一个NSArray一起使用,当该属性被捕获到另一个对象中时,该NSArray实际上需要被复制。例如,如果您将一个NSMutableArray对象分配给一个具有copy属性的NSArray类型的属性,则您确实希望创建muta的副本从该点开始,将其作为不可变属性“捕获”为不可变数组


    Marc采用了正确的方法,通常不会将NSMutableArray作为对象的公共API的一部分。如果您有公共属性,它可以是具有copy属性的NSArray。

    在这个回答中,我提出了一个在不破坏封装的情况下公开可变集合的解决方案。答案不适合这个问题因为它只适用于<代码>只读<代码>属性。以下是指向尼古拉答案的工作链接: