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

tac*_*cos 26 inheritance subclass objective-c ios

在超类中MyClass:

@interface MyClass : NSObject

@property (nonatomic, strong, readonly) NSString *pString;

@end

@implementation MyClass

@synthesize pString = _pString;

@end
Run Code Online (Sandbox Code Playgroud)

在子类中 MySubclass

@interface MySubclass : MyClass

@end

@implementation MySubclass

- (id)init {
    if (self = [super init]) {
        _pString = @"Some string";
    }
    return self;
}
Run Code Online (Sandbox Code Playgroud)

问题是编译器不认为它_pString是成员MySubclass,但我在访问它时没有问题MyClass.

我错过了什么?

das*_*ght 54

实例变量_pString所生产@synthesize私人MyClass.您需要对其进行保护才能MySubclass访问它.

_pString在这@protected部分中添加一个ivar声明MyClass,如下所示:

@interface MyClass : NSObject {
    @protected
    NSString *_pString;
}

@property (nonatomic, strong, readonly) NSString *pString;

@end
Run Code Online (Sandbox Code Playgroud)

现在像往常一样合成访问器,你的子类可以访问你的变量.

  • @Owl您将无法通过属性设置字符串,但您可以将字符串设置为支持变量,这将使`pString`属性的效果更改其值.你需要设置`_pString = @"abc"`,而不是`self.pString = @"abc"`. (2认同)

bor*_*den 5

我熟悉这个问题.您在.m类中合成变量,因此它不会与标头一起导入,因为_pString变量将作为实现的一部分创建,而不是接口.解决方案是在头部接口中声明_pString,然后无论如何合成它(它将使用现有变量而不是创建私有变量).

@interface MyClass : NSObject
{
    NSString *_pString; //Don't worry, it will not be public
}

@property (nonatomic, strong, readonly) NSString *pString;

@end
Run Code Online (Sandbox Code Playgroud)