具有合成readonly属性的类的子类无法访问Objective-C中的实例变量

时间:2012-06-08 04:23:25

标签: objective-c ios inheritance subclass

在超类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;
}

问题是编译器不认为_pStringMySubclass的成员,但我在MyClass中访问它时没有问题。

我错过了什么?

3 个答案:

答案 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.mMySubclass.m中。

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

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

此备选方案允许您使用访问者self.pString而不是ivar _pString

注意:您仍然需要保留pStringMyClass.h的定义。