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

10,847

Solution 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.

Solution 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
Share:
10,847

Related videos on Youtube

tacos_tacos_tacos
Author by

tacos_tacos_tacos

Updated on June 05, 2022

Comments

  • tacos_tacos_tacos
    tacos_tacos_tacos about 2 years

    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?

    • TeaCupApp
      TeaCupApp about 12 years
      try [super setPString:] or [self setPString:]
    • Dinesh
      Dinesh about 12 years
      tried to remove readonly property like below @property (nonatomic, strong) NSString *pString;
  • borrrden
    borrrden about 12 years
    Yes, you will...if it is from a subclass that has access to the underlying variable.
  • Sergey Kalinichenko
    Sergey Kalinichenko about 12 years
    @Owl You will not be able to set the string through the property, but you will be able to set the string to the backing variable, which will have the effect of pString property changing its value. You need to set _pString = @"abc", not self.pString = @"abc".
  • borrrden
    borrrden about 12 years
    @Owl what dasblinken said! You don't HAVE to set the variable through its property interface. This way objects that don't inherit from the class cannot change the variable. It is readonly except to children.
  • borrrden
    borrrden about 12 years
    Just a semantic question about stack...does "oldest" answer go by creation time or edit time?
  • tacos_tacos_tacos
    tacos_tacos_tacos about 12 years
    This was exactly what I was looking for. Thanks
  • SmileBot
    SmileBot about 10 years
    Good answer. I would personally use a double under score to indicate that you are accessing a protected ivar on a superclass and explicitly @synthesize it:
  • Rudolf Real
    Rudolf Real over 7 years
    A small reminder: in the subclass use the ivar (_myVariable) instead of the accessor (self.myVariable).