Защитное копирование Objective-C в методах доступа

Исходя из опыта 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;  

создаст копию аргумента установщика перед назначением его свойству customerList. Что меня смущает, так это написание подходящего геттера. Пока это выглядит так:

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

которая работает для всех внутренних вызовов методов, таких как self.customerList =..., но передала бы прямой указатель на любой внешний вызов, создавая нарушение безопасности. Я подумывал о том, чтобы предоставить другой публичный получатель, который бы возвратил копию, но хотел бы избежать этого, так как для этого нужно было бы использовать нетрадиционное имя. Как бы вы пошли об этой ситуации?
Спасибо.

2 ответа

Вы можете переопределить -customerList реализация должна быть: return [_customerList copy];, Имейте в виду, что обычно другие не ожидают, что средства доступа будут работать, поэтому обязательно документируйте это.

Если вы хотите вернуть копию, подкрепленную свойством и его получателем, использовать эту форму довольно просто:

@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
Другие вопросы по тегам