문제

I am working on a subclass of SKNode called UtilityNode

@implementation UtilityNode

- (id)initWithName:(NSString *)rootName {
    self = [super init];
    if(self) {
        [self setName:rootName]; // ?
    }
    return self;
}

@end

I am setting up a designated initialiser for the new node initWithName: where I am trying to initialise the name of the superclass SKNode when creating the new subclass. I was under the impression that I could just write _name = rootName; but _name was flagged as undeclared. I have got it working (as you can see above) by using [self setName:rootName]; Can anyone shine some light on this, am I doing this correctly?

도움이 되었습니까?

해결책

This is correct. The _name instance variable was probably declared as @private (the default for auto-synthesizing properties) and therefore it is inaccessible by subclasses.

In well-designed class hierarchies and specifically framework classes for which there is no source code available you will find most if not all instance variables inaccessible by subclasses because it hides the implementation detail and makes future changes to the base class possible. Imagine if the base class needed to verify the name property whenever it changes - if subclasses could assign directly to the ivar they would bypass the checks added to the ivar setter method.

PS: I find dot notation friendlier on the eyes:

 self.name = rootName;

UPDATE regarding the "don't send messages to self in init/dealloc" rule:

This can easily be avoided by redesigning the class to not take non-essential parameters in its init method. A cleaner version of this subclass would be:

UtilityNode* un = [UtilityNode node];
un.name = @"some name";

If the node absolutely requires the parameter to be set, warn the user via an NSAssert in the method where the name is required to be valid.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top