在Objective-C中拥有一个可公开变通的只读数组属性的最有效方法是什么?

时间:2014-11-23 04:49:05

标签: objective-c

我最近在this question关于如何最好地实现具有基础可变的只读,不可变数组属性的评论中遇到了一个小的(但不是不友好的)分歧在Objective-C中存储。 (此后评论已移至聊天中。)

首先,让我清楚一下我的想法。

  1. 我想要一个只读的属性,即它不可分配。 myObject.array = anotherArray应该失败。
  2. 我希望该属性的类型为不可变,以便无法通过属性本身添加新元素。显然,这意味着属性的类型应为NSArray
  3. 我希望该属性的存储(即ivar)为 mutable ,因为我将在包含的类上提供方法来改变它。
  4. 由于某些人似乎不太清楚,让我强调一下这个问题是关于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与它创建的名称相同,那么它只使用提供的名称。那我为什么要用呢?我认为它增加了清晰度和信号意图。如果你不喜欢它,想象一下它不在那里。它与这个问题没有密切关系。

    问题不在于是否想要一个公开的,不可变的和私人可变的财产是一个好主意。关于这是否是实现该目标的最有效方式(在语法和时钟周期方面)。我相信它是,但我想听听社区的意见,并且完全愿意改变主意。

1 个答案:

答案 0 :(得分:3)

  
      
  1. 我想要一个只读的属性,即它不可分配。 myObject.array = anotherArray应该失败。
  2.   
  3. 我希望该属性的类型是不可变的,以便不能通过属性本身添加新元素。显然,这意味着属性的类型应该是NSArray。
  4.   
  5. 我希望该属性的存储(即ivar)是可变的,因为我将在包含的类上提供方法来改变它。
  6.   

好吧,我将在另一个问题的评论中给出同样的答案。我所做的是:

  1. 在公共接口中将属性声明为readonly copy NSArray属性。这照顾你的1和2;这个东西现在无法写入,它是一个不可变的数组。

  2. .m 文件中私下重新声明属性readwrite。现在我必须从这个课程中分配给它。为了实现一个变异方法,我用mutableCopy读取,调用一个NSMutableArray方法,然后设置 - 从而再次自动获得一个不可变的NSArray。尽管使用了“复制”这个词,但实际上并没有开销。