由NSMutableArray支持的NSArray @property

我已经定义了一个类,我希望一个公有属性显示好像它是由一个NSArray支持的。 这很简单,但在我的情况下,真正的支持ivar是一个NSMutableArray

 @interface Foo { NSMutableArray* array; } @property (nonatomic, retain) NSArray* array; @end 

在我的实现文件( *.m )我@synthesize属性,但我立即遇到警告,因为使用self.words是试图修改NSArray

什么是正确的方法来做到这一点?

谢谢!

我会在头文件中声明一个readonly NSArray ,并重写该数组的getter,以返回在实现中声明的私有NSMutableArray的副本。 考虑以下。

foo.h中

 @interface Foo @property (nonatomic, retain, readonly) NSArray *array; @end 

Foo.m

 @interface Foo () @property (nonatomic, retain) NSMutableArray *mutableArray @end #pragma mark - @implementation Foo @synthesize mutableArray; - (NSArray *)array { return [[self.mutableArray copy] autorelease]; } @end 

基本上,将NSArray属性放在头文件的类别中,并将类扩展中的NSMutableArray属性放在实现文件中。 像这样…

foo.h中:

 @interface Foo @end @interface Foo (Collections) @property (nonatomic, readonly, strong) NSArray *someArray; @end 

Foo.m

 @interface Foo () @property (nonatomic, readwrite, strong) NSMutableArray *someArray; @end 

简单:

1)不要使用财产时,不是一个。

2)代码简化为:

 - (NSArray *)currentArray { return [NSArray arraywithArray:mutableArray]; // need the arrayWithArray - otherwise the caller could be in for surprise when the supposedly unchanging array changes while he is using it. } - (void)setArray:(NSArray *)array { [mutableArray setArray:array]; } 

当对象被分配时创build数组,当它死亡时,释放数组。

当仅仅使用'。'就会产生大的效果。 运营商,其容易忽略巨大的低效率的代码。 访问者就是这样。 另外 – 如果有人打电话给一个Foo.array,那么合同就是访问foo的数组成员,但是在调用的时候它真的只是一个副本。 这个差别是真实的,它导致在这里发布的其他实现中的错误。

更新:这个答案不再有效。 使用下面的build议解决scheme之一。

这几天你可以做到以下几点:

Foo.m:

 @implementation Foo { NSMutableArray* _array; } @end 

foo.h中:

 @interface Foo @property (readonly, strong) NSArray* array; @end 

你仍然可以通过ivar从实现内部解决mutarray_array,并且可以通过不可变属性访问它。 不幸的是,这并不能保证其他人不能将其转换为NSMutableArray并进行修改。 为了更好地保护您的白痴,您必须定义访问器方法并返回不可变的副本,但是在某些情况下,这可能会非常昂贵。

我实际上同意上面的意见之一,如果你需要返回一些只读数据,最好使用简单的访问器方法,这肯定不太模糊。

这是因为你的财产必须符合实际伊娃的types。

一个可能的解决scheme/解决方法:

 //Foo.h: @interface Foo { NSMutableArray* mutableArray; } @property (readwrite, nonatomic, retain) NSArray* array; //or manual accessor declarations, in case you're picky about wrapper-properties. @end //Foo.m: @interface Foo () @property (readwrite, nonatomic, retain) NSMutableArray* mutableArray; @end @implementation @synthesize mutableArray; @dynamic array; - (NSArray *)array { return [NSArray arrayWithArray:self.mutableArray]; } - (void)setArray:(NSArray *)array { self.mutableArray = [NSMutableArray arrayWithArray:array]; } @end 

你正在类扩展中添加一个私有的mutableArray属性,并使公有array简单地转发给你的私有可变的。

随着ObjC的最新语言扩展我倾向于删除

 { NSMutableArray* mutableArray; } 

如果可能的话,完全禁食。

并通过综合来界定伊娃,因此:

 @synthesize mutableArray = _mutableArray; 

这将生成一个NSMutableArray *_mutableArray; 实例为你。

最简单的答案: 您的属性types(NSArray)不匹配您的实例variablestypes(NSMutableArray)。

这是另一个很好的理由, 你不应该定义你自己的支持variables。 让@synthesize设置你的实例variables; 不要用手去做。