我最近在this question关于如何最好地实现具有基础可变的只读,不可变数组属性的评论中遇到了一个小的(但不是不友好的)分歧在Objective-C中存储。 (此后评论已移至聊天中。)
首先,让我清楚一下我的想法。
myObject.array = anotherArray
应该失败。NSArray
。由于某些人似乎不太清楚,让我强调一下这个问题是关于frogs
以下FrogBox
类的FrogBox
属性,仅此而已。
我将使用链接问题中相同的人为例子,一盒青蛙,名为@interface FrogBox : NSObject
@property (nonatomic, readonly) NSArray *frogs;
- (void)addFrog:(Frog*)frog;
- (void)removeFrog:(Frog*)frog;
@end
@implementation FrogBox {
NSMutableArray *_frogs;
}
@dynamic frogs;
- (instancetype)init {
self = [super init];
if (self) {
_frogs = [NSMutableArray array];
}
return self;
}
- (NSArray*)frogs {
return _frogs;
}
- (void)addFrog:(Frog*)frog {
[_frogs addObject:frog];
}
- (void)removeFrog:(Frog*)frog {
// Frog implements isEqual and hash.
[_frogs removeObject:frog];
}
@end
:
@dynamic
现在,让我们解决一些问题。 @dynamic
指令在这里并不是必需的。使用frogs
会抑制{{1}}属性的自动合成ivar。当然,如果自动合成看到的ivar与它创建的名称相同,那么它只使用提供的名称。那我为什么要用呢?我认为它增加了清晰度和信号意图。如果你不喜欢它,想象一下它不在那里。它与这个问题没有密切关系。
问题不在于是否想要一个公开的,不可变的和私人可变的财产是一个好主意。关于这是否是实现该目标的最有效方式(在语法和时钟周期方面)。我相信它是,但我想听听社区的意见,并且完全愿意改变主意。
答案 0 :(得分:3)
- 我想要一个只读的属性,即它不可分配。 myObject.array = anotherArray应该失败。
- 我希望该属性的类型是不可变的,以便不能通过属性本身添加新元素。显然,这意味着属性的类型应该是NSArray。
- 我希望该属性的存储(即ivar)是可变的,因为我将在包含的类上提供方法来改变它。
醇>
好吧,我将在另一个问题的评论中给出同样的答案。我所做的是:
在公共接口中将属性声明为readonly copy
NSArray属性。这照顾你的1和2;这个东西现在无法写入,它是一个不可变的数组。
在 .m 文件中私下重新声明属性readwrite
。现在我必须从这个课程中分配给它。为了实现一个变异方法,我用mutableCopy
读取,调用一个NSMutableArray方法,然后设置 - 从而再次自动获得一个不可变的NSArray。尽管使用了“复制”这个词,但实际上并没有开销。