Написать только свойство в Objective-C

Я застрял с объективными свойствами. Что мне нужно, это назначить свойство только для записи для переменной, в точности противоположное readonly, то есть переменная может иметь setMethod, но это не должно иметь getMethod, Я не знаю, как это сделать. ответы с некоторыми фрагментами кода приветствуются.

3 ответа

Решение

Вы можете сделать что-то вроде:

@interface MyClass {
@private
int _var;
}

- (void)setVar:(int)newVar;
@end

@implementation MyClass
- (void)setVar:(int)newVar {
_var = newVar;
}
@end

Теперь вы можете получить доступ к переменной var как свойство, предназначенное только для записи:

@implementation SomeOtherClass
...
MyClass c = [[MyClass alloc] init];
c.var = 3;
...
@end

И если вы попытаетесь прочитать поддельное свойство, компилятор предупредит вас.

Другой верный подход - объявить обычное свойство и сделать геттер недоступным.

@interface MyClass
@property NSString * var;
- (NSString *)var UNAVAILABLE_ATTRIBUTE;
@end

Это вызовет ошибку времени компиляции в случае, если кто-то попытается получить доступ к получателю.


Основным преимуществом этого подхода является то, что у вас фактически есть ТМ реального свойства, а не суррогат, подделанный переменной экземпляра и установщиком, что подразумевает, что:

  • вы получите автозаполнение при использовании точечной нотации в Xcode
  • все функции времени выполнения, такие как class_getProperty а также class_copyPropertyList будет работать как положено.

Тем не менее, реализация getter в любом случае синтезируется и может быть вызвана с использованием чего-то вроде

NSString * string = [myObj performSelector:@selector(var)];

или используя NSInvocation (в случае отсутствияid имущество)

Если вы параноик и действительно хотите запретить клиенту вызывать метод получения, вы можете явно вызвать исключение, предоставив свою собственную реализацию.

@implementation MyClass
- (int)var {
    [NSException raise:NSInternalInconsistencyException
                format:@"property is write-only"];
}
@end

В любом случае, если кто-то серьезно хочет вмешаться в вашу переменную экземпляра, он может использовать среду выполнения для доступа к ней, поэтому последняя предосторожность, вероятно, бесполезна с учетом варианта использования. Ошибка времени компиляции - это то, что вы действительно ищете.

Есть ли причина, по которой это должно быть собственностью? Я бы просто объявил сеттер как метод и использовал бы обычный [foo setVar:bar] синтаксис.

Другие вопросы по тегам