-1

I have a base class who's constructor sets the objects state given some external data:

@implementation XMlContent

     - (id)initWithParser:(NSXMLParser *)xmlParser {
        self = [super init];
        if (self) {
            if(xmlParser != nil){
            _documentFormat = @"xml";
            _xmlParser = xmlParser;
            xmlParser.delegate = self;
            } else{
                return nil;
            }
        }
        return self; }

I have a subclass of this object and I have overridden this constructor like so (probably wrong):

@implementation AtomContent
      - (id)initWithParser:(NSXMLParser *)xmlParser
    {
        self = [super init];
        if (self) {
            if(xmlParser != nil){
                self.xmlParser = xmlParser;
                self.xmlParser.delegate = self;
                self.documentFormat = @"atom";
            } else{
                return nil;
            }
        }
        return self;
    }

The issue I have is that when creating an instance of the subclass (AtomContent in this case) I get back an instance of the superclass and thus superclass methods are called rather than those in the subclass. Looking at my subclass constructor its obvious why. My question is how do I property implement the subclass constructor so the super class is init'd but references to 'self' are to the subclass? Should I not override the constructor but rather use setters to set object state?

Corrections

I get back an instance of the superclass and thus superclass

-No. Specifically my issue is that base class implementation is used (the NSXMLParser delegate methods) rather than the subclass'. I am, indeed, returned an instance of the subclass.

constructor

-Yeah ok.. "Initializer"

Thanks!

4

1 回答 1

6

You're not calling the designated initializer from your subclass initializer, which causes you to need to repeat a lot of work in the subclass's initWithXMLParser: implementation. Here's how I'd do it:

// Superclass
- (id)initWithParser:(NSXMLParser *)xmlParser {
    self = [super init];
    if (self) {
        if(xmlParser != nil) {
            _documentFormat = @"xml";
            _xmlParser = xmlParser;
            xmlParser.delegate = self;
        }
        else {
            return nil;
        }
    }

    return self; 
}

// Subclass
- (id)initWithParser:(NSXMLParser *)xmlParser
{
    self = [super initWithParser:xmlParser];
    if (self) {
        self.documentFormat = @"atom";
    }
    return self;
}

I should add that if you are truly getting an instance of the superclass returned, then your problem would be in allocation, not initialization, as the isa pointer and hence the method lookup tables are set inside alloc and thus are set at the time init is called. I would rate the chance of that being your problem in actuality as being low.

于 2013-09-04T19:56:56.450 回答