Snowman
Snowman

Reputation: 32091

Inherited properties and synthesizing in Objective-C

I have the following class and subclass:

@interface NSHigh : NSObject
@property (nonatomic, strong) NSArray *array;
@end
@implementation NSHigh
-(NSArray*)array
{
    _array = [[NSArray alloc] init];
    return _array;
}
@end

@interface NSLow : NSHigh
@end
@implementation NSLow
/* synthesizing makes the assertion FAIL. NO synthesizing makes the assertion PASS */
@synthesize array;
@end

Then I run this code somewhere:

NSLow *low = [[NSLow alloc] init];
assert(low.array);

So, apparently, if in the subclass NSLow I synthesize the array property, then the getter from the super class does not get called, and the assertion fails.

If I do not synthesize, then the superclass getter is called, and the assertion passes.

  1. Why does this happen?
  2. How would I access the array instance variable in the NSLow subclass without calling self.array every time?

Upvotes: 3

Views: 3991

Answers (1)

DrummerB
DrummerB

Reputation: 40211

@synthesize in NSLow will create the following getter:

- (NSArray *)array {
    return _array;
}

So, your array is never initialized and nil is returned.

You generally shouldn't use @synthesize for @properties that are declared in a superclass.

Also, you shouldn't implement a getter like the one in NSHigh. If you want to init that array lazily you should do it like this:

- (NSArray *)array {
    if (!_array) {
        _array = [[NSArray alloc] init];
    }
    return _array;
}

Finally, you shouldn't use NS prefix.

EDIT:

If you want direct access to your ivar in the subclass, you can explicitly declare it in the header like this:

@interface NSHigh : NSObject {
    NSArray *_array;
}
@property (nonatomic, strong) NSArray *array;
@end

This will allow you to access the ivar in your subclasses too.

Upvotes: 8

Related Questions