开发者

Synthesized property of a protocol not seeing superclass' ivar

I have a situation where my subclass is not seeing the superclass' instance variable x. The ivar is obviously @protected by default, so why do I get a compiler error "x undeclared"?

- (CGSize)hitSize
{
    // Compiler error
    return size;
}

EDIT: hitSize is a property of a protocol my subclass is confo开发者_运维百科rming to. The problem was that I had hitSize @synthesized, which was the culprit. The question then is why can't the synthesized getter see the ivar?

EDIT: Now that I found out the problem, I edited the question to ask why this is an error.


Joanna's answers are both correct (though ivar synthesis doesn't kick in on 32 bit Mac OS X).

The reason, though, is because allowing a subclass to synthesize access to a superclass's internal state would quite explicitly break encapsulation. The decision was made to explicitly not allow that particular pattern in all cases, even within a single framework.

If a superclass provides storage for something, it should provide the access control and encapsulate the management of said memory. If a subclass needs to customize access, do so with care by overriding the getter/setter [and, preferably, calling the super to actually get/set the value].


You can also use the explicit getter/setter attributes to access, even the @private ivars of the base class:


@interface Base : NSObject
{
  @protected
    int intVar;
}

@end

@interface Derived : Base
{
}

@property (assign, getter = intVar, setter = intVar) int aVar;

@end


Synthesized properties not only synthesize the getters and setters, they also synthesize the ivar if one is not declared.

You need to write explicit accessors in the subclass and access the@protected ivar via the self->myIvar syntax.


Thanks bbum, for elaborating on my replies.

With regard to your second reply, you are, of course, right and, in that case, you can "do things right", using a class extension to hide the property on the base class, like this:

// Example.h
@interface Base : NSObject
{
  @private
    int intVar;
}

@end

@interface Derived : Base
{
}

@property (assign) int aVar;

@end
// Example.m
@interface Base ()

@property (assign) int intVar;

@end

@implementation Base

@synthesize intVar;

@end;

@implementation Derived

- (int) aVar
{
  return self.intVar;
}

- (void) setAVar:(int)value
{
  self.intVar = value;
}

@end
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜