26

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

我错过了什么?

4

3 回答 3

54

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

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

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

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

@end

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

于 2012-06-08T04:35:09.523 回答
5

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

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

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

@end
于 2012-06-08T04:30:08.980 回答
0

给定的答案非常好。这是一个替代答案,显然 Apple更喜欢.

你可以为你的类定义一个私有扩展MyClass+Protected.h,一个文件,它需要包含在MyClass.m和中MySubclass.m

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

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

这种替代方法允许您使用访问器self.pString而不是 ivar _pString

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

于 2017-01-17T15:39:10.170 回答