4

来自 Java 背景,我在想办法在 Objective-C 中进行防御性编程时遇到了麻烦。
假设SomeClass是可变的并提供了一个复制方法,这是我用 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 属性之前,会对其进行复制。让我困惑的是写一个合适的吸气剂。到目前为止,它看起来像这样:

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

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

4

2 回答 2

3

-customerList您可以将实现覆盖为: return [_customerList copy];. 请注意,这通常不是其他人期望访问器工作的方式,因此请务必记录下来。

于 2013-01-05T18:55:01.617 回答
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

尽管您可以实现自己的 getter —— 正如 Carl 所提到的,这在 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
于 2013-07-10T05:02:58.770 回答