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

假装没事ソ 提交于 2019-11-27 02:05:00

问题


In the superclass MyClass:

@interface MyClass : NSObject

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

@end

@implementation MyClass

@synthesize pString = _pString;

@end

In the subclass MySubclass

@interface MySubclass : MyClass

@end

@implementation MySubclass

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

The problem is that the compiler doesn't think that _pString is a member of MySubclass, but I have no problem accessing it in MyClass.

What am I missing?


回答1:


The instance variable _pString produced by @synthesize is private to MyClass. You need to make it protected in order for MySubclass to be able to access it.

Add an ivar declaration for _pString in the @protected section of MyClass, like this:

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

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

@end

Now synthesize the accessors as usual, and your variable will become accessible to your subclass.




回答2:


I am familiar with this problem. You synthesize the variable in your .m class, so it is not imported along with the header since the _pString variable will be created as part of the implementation, and not the interface. The solution is to declare _pString in your header interface and then synthesize it anyway (it will use the existing variable instead of creating a private one).

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

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

@end



回答3:


The given answer works perfectly fine. This is an alternative answer, that apparently Apple likes a bit more.

You can define a private extension of your class, a MyClass+Protected.h file, which needs to be included in MyClass.m and MySubclass.m.

Then, in this new file, you redefine the property as readwrite.

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

This alternative allows you to use the accessor self.pString rather than the ivar _pString.

Note: you still need to keep the definition of pString in your MyClass.h as is.



来源:https://stackoverflow.com/questions/10943042/subclass-of-class-with-synthesized-readonly-property-cannot-access-instance-vari

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!