假设我有一个包含可变数组的类。我想确保如果其他类要求数组,它们将获得一个非可变类型,但在拥有类中,它实际上是NSMutableArray
的一个实例,因此我可以添加和删除项。< / p>
#import "Person.h"
@class Asset;
@interface Employee : Person
{
NSMutableArray *_assets;
}
@property (nonatomic,copy) NSArray *assets;
-(void)addAssets:(Asset *)a;
问题是,我是否必须将访问器方法修改为类似的东西,还是会自动表现得像我想要的那样?
#import "Employee.h"
#import "Asset.h"
@implementation Employee
/* Accessors for assets properties
-(NSArray *)assets
{
return [_assets copy];
}
-(void)setAssets:(NSArray *)assets
{
_assets = [assets mutableCopy ];
}
*/
-(void)addAssets:(Asset *)a
{
//is assets nil?
if (!_assets) {
//Create Array
_assets = [[NSMutableArray alloc]init];
}
[_assets addObject:a];
}
答案 0 :(得分:2)
ppalancica's answer不正确。 copy
属性仅表示设置者在设置属性时获取副本。合成的getter将不返回副本。您必须自己实施该行为:
- (NSArray *)assets
{
return [_assets copy];
}
您可能想制作不制作副本的内部访问者。你也可以redeclare the property privately;然后将签订客户端代码以将其请求的数组视为不可变的。
此代码演示了合成的getter返回未复制的对象:
#import <Foundation/Foundation.h>
@interface ArrayReturner : NSObject
@property (copy, nonatomic) NSArray * array;
@end
@implementation ArrayReturner
{
NSMutableArray * _array;
}
- (BOOL)myArrayIsIdenticalTo:(NSArray *)otherArray
{
return _array == otherArray;
}
@end
int main(int argc, const char *argv[])
{
@autoreleasepool {
ArrayReturner * a = [ArrayReturner new];
[a setArray:@[@1, @2]];
NSArray * returnedArray = [a array];
// Does not throw
NSCAssert([a myArrayIsIdenticalTo:returnedArray],
@"Returned array is a separate instance.");
}
return 0;
}
答案 1 :(得分:0)
因为你已经指定了属性&#34; copy&#34;对于数组属性,不需要覆盖getter和setter。编译器将为您完成所有繁重的工作。
如果你指定&#34; strong&#34;相反,getter和setter看起来像:
-(NSArray *)assets
{
return _assets;
}
-(void)setAssets:(NSArray *)assets
{
_assets = assets;
}
这可能是个问题。
实际上有一个WWDC会议解释了所有这些细节。对于NSString属性,建议使用copy,你可以在iOS SDK框架中看到它很多。