Написать только свойство в Objective-C - PullRequest
29 голосов
/ 24 ноября 2010

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

Ответы [ 3 ]

49 голосов
/ 05 сентября 2013

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

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

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


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

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

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

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

или с использованием NSInvocation (в случае свойства, отличного от id)

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

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

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

12 голосов
/ 24 ноября 2010

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

@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

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

5 голосов
/ 24 ноября 2010

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...