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



来自Java背景,我很难找到在Objective-C中进行防御性编程的方法。
假设 someeclass 是可变的,并且提供了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属性之前,会复制该参数。让我困惑的是如何写一个合适的getter。到目前为止,它看起来像这样:

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

适用于所有内部方法调用,如self。customerList =…,但会将一个直接指针传递给任何造成安全漏洞的外部调用。我正在考虑提供一个不同的公共getter来返回一个副本,但希望避免使用它,因为它需要一个非常规的名称。你会如何处理这种情况?
谢谢你!

您可以覆盖-customerList实现为:return [_customerList copy];。请注意,这通常不是其他人所期望的访问器的工作方式,因此请确保对此进行记录。

如果你想返回一个由属性及其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

尽管你可以实现你自己的getter——这在ObjC中是非常规的,正如Carl提到的。

另一种方法是为实际的属性使用不同的名称:

@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

最新更新