Могу ли я создавать свойства с помощью общедоступного getter и private setter?

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

foo.h:

@interface Foo {
  NSString *bar;
}
@property (readonly) NSString *bar;
@end

Foo.m:

#import "Foo.h"

@interface Foo ()
@property (copy) NSString *bar;
@end

@implementation Foo
@synthesize bar;
@end

Но это порождает предупреждение:

Foo.m:4: warning: property ‘bar’ attribute in ‘Foo’ class continuation does not match class ‘Foo’ property

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

Ответы

Ответ 1

Ваш подход правильный, но переопределение @property bar в расширении класса должно соответствовать исходному объявлению, кроме readwrite vs. readonly. Итак, это сработает:

foo.h

@interface Foo {
  NSString *bar;
}
@property (copy,readonly) NSString *bar;
@end

Foo.m:

#import "Foo.h"

@interface Foo ()
@property (copy,readwrite) NSString *bar;
@end

@implementation Foo
@synthesize bar;
@end

(напомним, что значение по умолчанию assign для свойств, а не copy).

Ответ 2

Когда Барри говорит, что "значение по умолчанию сохраняется для свойств", он означает, что сохранение должно быть указано следующим образом:

@property (retain) NSDate *endDate;

Если они оставлены следующим образом:

@property NSDate *endDate;

assign принимается компилятором.