由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; 不要用手去做。