Objective-C在访问器方法中的防御性复制

时间:2013-01-05 18:49:24

标签: objective-c defensive-programming defensive-copy

来自Java背景,我无法找到在Objective-C中进行防御性编程的方法。
假设 SomeClass 是可变的并提供 copy 方法,这是我用Java编写的典型代码:

public MyClass  
{ 
    private SomeClass customerList;
    ...
    public SomeClass getCustomerList() {
        return this.customerList.copy(); 
    }
    public void setCustomerList(SomeClass list) {
        this.customerList = list.copy();
    }
}

我花了一些时间才弄清楚

@property (nonatomic, copy) SomeClass *customerList;  

在将setter参数分配给customerList属性之前会复制该setter的参数。 令我困惑的是写一个合适的吸气剂。到目前为止它看起来像这样:

(SomeClass *)customerList {  
    if(!_customerList) {  
        _customerList = [[SomeClass alloc] init];
    }
    return _customerList;
}  

适用于所有内部方法调用,如self.customerList = ...,但会直接指向任何创建安全漏洞的外部调用。我正在考虑提供一个不同的公共吸气剂,它会返回一份副本,但我想避免它,因为它需要一个非传统的名称。您如何处理这种情况?
谢谢。

2 个答案:

答案 0 :(得分:3)

您可以将-customerList实施覆盖为:return [_customerList copy];。请注意,其他人通常不希望访问者如何工作,因此请务必记录下来。

答案 1 :(得分:0)

如果要返回由属性及其getter支持的副本,使用此表单非常简单:

@interface MyClass : NSObject
- (SomeClass *)copyCustomerList;
@end

@interface MyClass ()
@property (nonatomic, copy) SomeClass * customerList; // hide what you can
@end

@implementation MyClass
- (SomeClass *)copyCustomerList { return self.customerList.copy; }
@end

虽然你可以改为实现自己的吸气剂 - 但正如卡尔所提到的那样,它在ObjC中是非常规的。

您可以采取的另一种方法是为实际属性使用不同的名称:

@interface MyClass : NSObject
- (SomeClass *)customerList;
@end

@interface MyClass ()
@property (nonatomic, copy) SomeClass * privCustomerList;
@end

@implementation MyClass

- (SomeClass *)customerList
{
 // -autorelease if MRC
 return self.privCustomerList.copy;
}

@end