将Obj-C 2.0属性与可变对象(如NSMutableArray)一起使用的最佳方法是什么?
-
03-07-2019 - |
题
我有一个具有NSMutableArray属性的Obj-C 2.0类。如果我使用下面的代码,那么合成的setter将给我一个不可变的副本,而不是一个可变的副本:
@property (readwrite, copy) NSMutableArray *myArray;
有没有理由说Apple没有实现以下语法?
@property (readwrite, mutablecopy) NSMutableArray *myArray;
由于我们没有 mutablecopy
,处理这种(看似常见的)情况的最佳方法是什么?我应该编写自己的setter来执行-mutableCopy吗?
解决方案
如前所述,正确的方法这样做不是为了使可变数组成为属性。有一个很好的解释,你应该实现什么,以符合KVC 这里。
其他提示
前段时间我遇到了同样的问题,发现 Apple Developer Connection上的文档建议您提供自己的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中传递 NSMutableArray
并不常见。标准Cocoa实践将实现符合键值的编码方法,用于索引到多个属性。这有两个好处:
- 键值观察按预期工作(有几种情况下观察NSMutableArray导致不是你想要的行为)
- 您的数据结构的实现是隐藏的,因为您公开了变异方法(例如
- [MyObject insertObjectInMyProperty:(id)newObject atIndex:(NSUInteger)i]
,而不是数据结构本身。
醇>
请记住,在Cocoa中传递可变数组实际上并不常见。您可以使用私有可变数组作为内部存储,但使用普通NSArray对象创建方法以添加或获取对象。这可能就是没有mutablecopy属性声明的原因。
你必须自己写一个setter。
保留NSMutableArray的正确方法是使用retain属性:
@property (nonatomic, retain) NSMutableArray *myArray;
您无需编写自己的setter或使用副本。 copy属性应与NSArray一起使用,当将属性捕获到另一个对象时,实际上需要复制该NSArray。例如,如果将NSMutableArray对象分配给具有copy属性的NSArray类型的属性,那么您确实希望将可变数组的副本设置为“capture”。从那时起,它就是一个不可改变的财产。
Marc有正确的方法,通常不会让NSMutableArray成为对象的公共API的一部分。如果你有公共属性,它可以是带有copy属性的NSArray。