具有合成只读属性的类的子类不能访问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_pStringMyClass私有的 。 您需要使其受到保护才能使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.mMySubclass.m

然后,在这个新文件中,您将该属性重新定义为readwrite

 @interface MyClass () @property (strong, readwrite) NSString * pString; @end 

这个select允许你使用accessor self.pString而不是ivar _pString

注意:你仍然需要按照原样在MyClass.h保留pString的定义。