在超类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
是MySubclass
的成员,但我在MyClass
中访问它时没有问题。
我错过了什么?
答案 0 :(得分:54)
_pString
生成的实例变量@synthesize
私有到MyClass
。您需要将其设为 protected ,以便MySubclass
能够访问它。
在_pString
的{{1}}部分添加@protected
的ivar声明,如下所示:
MyClass
现在像往常一样合成访问器,你的子类可以访问你的变量。
答案 1 :(得分:5)
我熟悉这个问题。您在.m类中合成变量,因此它不会与标头一起导入,因为_pString变量将作为实现的一部分创建,而不是接口。解决方案是在头部接口中声明_pString然后合成它(它将使用现有变量而不是创建私有变量)。
@interface MyClass : NSObject
{
NSString *_pString; //Don't worry, it will not be public
}
@property (nonatomic, strong, readonly) NSString *pString;
@end
答案 2 :(得分:0)
给出的答案完全正常。这是一个替代答案,显然是Apple likes a bit more。
您可以定义一个private extension的班级MyClass+Protected.h
文件,该文件需要包含在MyClass.m
和MySubclass.m
中。
然后,在此新文件中,您将该属性重新定义为readwrite
。
@interface MyClass ()
@property (strong, readwrite) NSString * pString;
@end
此备选方案允许您使用访问者self.pString
而不是ivar _pString
。
注意:您仍然需要保留pString
中MyClass.h
的定义。