繁体   English   中英

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

[英]Subclass of class with synthesized readonly property cannot access instance variable in Objective-C

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

我错过了什么?

@synthesize生成的实例变量_pStringMyClass私有的 您需要对其进行保护 ,以便MySubclass能够访问它。

MyClass@protected部分添加_pString的ivar声明,如下所示:

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

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

@end

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

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

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

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

@end

给出的答案完全正常。 这是一个替代答案,显然Apple 喜欢更多

您可以定义类的私有扩展MyClass+Protected.h文件,该文件需要包含在MyClass.mMySubclass.m

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

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

此替代方法允许您使用访问者self.pString而不是ivar _pString

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM