具有合成只读属性的类的子类不能访问Objective-C中的实例variables
在超类MyClass
:
@interface MyClass : NSObject @property (nonatomic, strong, readonly) NSString *pString; @end @implementation MyClass @synthesize pString = _pString; @end
在子类MySubclass
@interface MySubclass : MyClass @end @implementation MySubclass - (id)init { if (self = [super init]) { _pString = @"Some string"; } return self; }
问题是,编译器不认为_pString
是_pString
的成员,但我没有问题在MyClass
访问它。
我错过了什么?
@synthesize
生成的实例variables_pString
对MyClass
是私有的 。 您需要使其受到保护才能使MySubclass
能够访问它。
在MyClass
的@protected
部分添加_pString
的ivar声明,如下所示:
@interface MyClass : NSObject { @protected NSString *_pString; } @property (nonatomic, strong, readonly) NSString *pString; @end
现在像往常一样综合访问器,你的variables可以被你的子类访问。
我很熟悉这个问题。 您在.m类中合成variables,因此不会将其与头一起导入,因为_pStringvariables将作为实现的一部分创build,而不是接口。 解决的办法是在你的头接口声明_pString,然后综合它(它将使用现有的variables,而不是创build一个私人的)。
@interface MyClass : NSObject { NSString *_pString; //Don't worry, it will not be public } @property (nonatomic, strong, readonly) NSString *pString; @end
给定的答案完美无瑕。 这是一个替代的答案,显然苹果喜欢多一点 。
您可以定义您的类的私有扩展 ,一个MyClass+Protected.h
文件,需要包含在MyClass.m
和MySubclass.m
。
然后,在这个新文件中,您将该属性重新定义为readwrite
。
@interface MyClass () @property (strong, readwrite) NSString * pString; @end
这个select允许你使用accessor self.pString
而不是ivar _pString
。
注意:你仍然需要按照原样在MyClass.h
保留pString
的定义。