0

I have classes defined roughly like so:

@interface ClassA : NSObject
@property BOOL propA;
@end

@interface ClassB : ClassA
@property BOOL propB;
@end

@interface ClassC : ClassB
@property BOOL propC;
@end

@interface ClassD : ClassC
@property BOOL propD;
@end

Now in my implementation file, I try the following:

@implementation ClassD

- (id) init
{
    self = [super init];

    if (self)
    {
        _propD = NO;
        // Fails because _propC is private, so I can't see it:
        _propC = NO;
        // Works:
        super.propC = NO;
        // Fails, because property "super.super" not found
        super.super.propB = NO;
        super.super.super.propA = NO;
    }

    return self;
}

@end

How can I set propB and propA in this case?

stevendesu
  • 15,753
  • 22
  • 105
  • 182
  • 1
    I'm not coding in Objc for awhile now, but why you don't use `self.propC` instead? – Mojtaba Hosseini Nov 22 '19 at 19:33
  • @MojtabaHosseini Of course, it seems so simple now :) I think maybe I tried that at one point and the auto-complete wasn't detecting it, so I assumed it wouldn't work. But I just tried it now and it worked perfectly. – stevendesu Nov 22 '19 at 19:35

3 Answers3

2

You may have no access to instance variables of the superclass directly, but you have access to the setters. So you can do it simply like:

- (id) init {
    self = [super init];

    if (self) {
        _propD = NO;
        self.propC = NO;
        self.propB = NO;
        self.propA = NO;
    }
}
Mojtaba Hosseini
  • 95,414
  • 31
  • 268
  • 278
1

Assuming OP really wanted to traverse the super-super-super class hierarchy (which is not the case as it turns out in the question) and actually call the method

@interface ClassA : NSObject
@property BOOL propA;
@end

@interface ClassB : ClassA
@property BOOL propA;
@end

@interface ClassC : ClassB
@property BOOL propA;
@end

@interface ClassD : ClassC
@property BOOL propA;
@end

this technically can be done, however is a bit cumbersome:

#import <objc/runtime.h>
#import <objc/message.h>
    ClassD* instance = [ClassD new];
    BOOL result;

    struct objc_super super = {
        .receiver = instance,
        .super_class = class_getSuperclass(instance.class)
    };

    BOOL (*objc_msgSendSuper_typed)(struct objc_super *, SEL) = (void *)&objc_msgSendSuper;
    //call super.propA - at this class hierarchy level obviously normal super.propA would suffice
    result = objc_msgSendSuper_typed(&super, @selector(propA));

    struct objc_super superSuper = {
        .receiver = instance,
        .super_class = class_getSuperclass(class_getSuperclass(instance.class))
    };

    //call "super.super".propA
    result = objc_msgSendSuper_typed(&superSuper, @selector(propA));

    struct objc_super superSuperSuper = {
        .receiver = instance,
        .super_class = class_getSuperclass(class_getSuperclass(class_getSuperclass(instance.class)))
    };

    //call "super.super.super".propA
    result = objc_msgSendSuper_typed(&superSuperSuper, @selector(propA));

Slightly more complicated variant of this with args covered also here.

Kamil.S
  • 5,205
  • 2
  • 22
  • 51
0

// Fails, because property "super.super" not found

That's because super isn't a property, but rather a keyword, like self.

Caleb
  • 124,013
  • 19
  • 183
  • 272