Я застрял со свойствами Objective-C. Что мне нужно, так это присвоить переменной свойство только для записи, прямо противоположное свойству только для чтения, т.е. переменная может иметь setMethod
, но не должна иметь getMethod
. Я не знаю, как это сделать. ответы с некоторыми фрагментами кода приветствуются.
Напишите только свойство в Objective-C
Ответы (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
И если вы попытаетесь прочитать поддельное свойство, компилятор предупредит вас.
-(void)setVar:(int)newVar
в реализации, а также в интерфейсе.
- person JeremyP; 24.11.2010
@property
, и поведение будет точно таким же, как и с @property
. То же самое относится и к сеттеру. Вы даже можете использовать запись через точку.
- person Sulthan; 18.02.2013
class_copyPropertyList
. Смотрите мой ответ для другого подхода.
- person Gabriele Petronella; 05.09.2013
Другой допустимый подход — объявить свойство normal и сделать геттер недоступным.
@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
В любом случае, если кто-то серьезно захочет изменить вашу переменную экземпляра, он может использовать среду выполнения для доступа к ней, поэтому последнее предостережение, вероятно, бесполезно, учитывая вариант использования. Ошибка времени компиляции - это то, что вы действительно ищете.
Есть ли причина, по которой это должно быть собственностью? Я бы просто объявил сеттер как метод и использовал обычный синтаксис [foo setVar:bar]
.