Объективные свойства ARC только для чтения и реализация частного сеттера

До ARC, если я хотел, чтобы свойство было доступно только для чтения для его использования, но имело возможность записи в классе, я мог сделать:

// Public declaration
@interface SomeClass : NSObject
    @property (nonatomic, retain, readonly) NSString *myProperty;
@end

// private interface declaration
@interface SomeClass()
- (void)setMyProperty:(NSString *)newValue;
@end

@implementation SomeClass

- (void)setMyProperty:(NSString *)newValue
{ 
   if (myProperty != newValue) {
      [myProperty release];
      myProperty = [newValue retain];
   }
}
- (void)doSomethingPrivate
{
    [self setMyProperty:@"some value that only this class can set"];
}
@end

С ARC, если бы я хотел переопределить setMyProperty, вы больше не могли бы использовать ключевые слова сохранения/освобождения, так что это адекватно и правильно?

// interface declaration:
@property (nonatomic, strong, readonly) NSString *myProperty;

// Setter override
- (void)setMyProperty:(NSString *)newValue
{ 
   if (myProperty != newValue) {
      myProperty = newValue;
   }
}

person Jonas Gardner    schedule 19.12.2011    source источник


Ответы (2)


Да, этого достаточно, но вам даже не нужно столько.

Ты можешь сделать

- (void)setMyProperty:(NSString *)newValue
{ 
      myProperty = newValue;
}

Здесь компилятор все сделает правильно.

Другое дело, что вам даже ЭТО не нужно. В расширении вашего класса вы можете фактически переопределить объявления @property.

@interface SomeClass : NSObject
@property (nonatomic, readonly, strong) NSString *myProperty;
@end

@interface SomeClass()
@property (nonatomic, readwrite, strong) NSString *myProperty;
@end

Для этого вам просто нужно синтезировать, и у вас есть частный сеттер, который синтезируется для вас.

person Joshua Weinberg    schedule 19.12.2011
comment
Спасибо Джошуа - очень полезно! С тех пор я озадачен одной последней вещью. Читая об изменениях свойств ARC здесь, кажется, что , по умолчанию они реализуются @synthesize с strong, а не assign. В этом случае, в интересах сделать общедоступный API чище, не лучше ли просто указать (неатомарное, только для чтения), поскольку пользователям общедоступного интерфейса не нужно заботиться или нужно знать, что внутренне свойство является сильным ? Надеюсь, я имею смысл здесь. :) - person Quintin Willison; 24.05.2012
comment
Это сильно только для типов объектов, чтобы сделать вещи более явными, я все еще предпочитаю ставить strong, weak или assign. - person Joshua Weinberg; 24.05.2012
comment
Действительно, strong применим только к типам объектов, но все еще остается вопрос, должен ли ваш общедоступный API (например, заголовочный файл) публиковать эту информацию. Это реальный момент, о котором я спрашивал! - person Quintin Willison; 25.05.2012
comment
Я предпочитаю сделать это так, чтобы быть более явным - person Joshua Weinberg; 25.05.2012
comment
Я задал аналогичный вопрос, я не уверен, что он что-то проясняет (я все еще не понимаю, что происходит под обложками) stackoverflow.com/questions/10694676/ - person Wayne Uroda; 14.08.2012

Вы можете повторно объявить свою собственность как readwrite в расширении интерфейса:

@interface SomeClass()
@property (nonatomic, strong, readwrite) NSString *myProperty;
@end
person iHunter    schedule 19.12.2011