Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/iphone/43.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Iphone 如何在Objective-C中正确实现子类构造函数_Iphone_Ios_Objective C - Fatal编程技术网

Iphone 如何在Objective-C中正确实现子类构造函数

Iphone 如何在Objective-C中正确实现子类构造函数,iphone,ios,objective-c,Iphone,Ios,Objective C,我有一个基类,它的构造函数在给定一些外部数据的情况下设置对象状态: @implementation XMlContent - (id)initWithParser:(NSXMLParser *)xmlParser { self = [super init]; if (self) { if(xmlParser != nil){ _documentFormat = @"xml"; _x

我有一个基类,它的构造函数在给定一些外部数据的情况下设置对象状态:

@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; }
我有这个对象的一个子类,我重写了这个构造函数,可能是错误的:

@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;
    }
我遇到的问题是,在本例中,当创建子类AtomContent的实例时,我会返回一个超类的实例,因此调用的是超类方法,而不是子类中的方法。看看我的子类构造函数,这是显而易见的原因。我的问题是,如何实现子类构造函数,使超类是init'd,而对“self”的引用是子类?我应该不重写构造函数,而是使用setter来设置对象状态吗

更正

我得到了超类的一个实例,从而得到了超类

-不。具体地说,我的问题是基类实现是由NSXMLParser委托方法而不是子类使用的。我确实返回了子类的一个实例

建造师

-是的,好的。。初始值设定项


谢谢

您没有从子类初始值设定项调用指定的初始值设定项,这导致您需要在子类的initWithXMLParser:实现中重复大量工作。我是这样做的:

// 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;
}

我应该补充一点,如果您真的得到了一个返回的超类实例,那么您的问题将是分配,而不是初始化,因为isa指针和方法查找表是在alloc中设置的,因此在调用init时设置的。我认为这实际上是你的问题的可能性很低。

你是如何实例化你的对象的?顺便说一句,在Objective-C中也没有构造函数,您确定要在AtomContent类中调用[super init]而不是[super initWithParser:xmlParser]吗?创建子类的实例时,我会返回一个超类的实例-这是错误的。@MartinR-好吧,对错。从某种意义上说,他确实得到了超类的一个实例,该实例由其子类定义的任何附加内容包装。如果您引用self.xyz,并且您尚未在子类中定义属性xyz,则将访问该属性的超类版本。一般来说,很少需要子类和超类定义相同的属性。非常感谢。你说得对,这样好多了。具体来说,我传递给-idinitWithParser:NSXMLParser*xmlParser的NSXMLParser似乎使用基类作为委托。这不是我想要的。我希望使用子类实现。我应该在setter而不是init方法中设置委托吗?在Objective-C中,所有方法都是动态调度的。当任何人调用任何方法时,执行的代码是继承层次结构中“最深”的实现。如果将AtomContent实例指定为NSXMLParser的委托,那么执行的代码将尽可能与AtomContent中的代码相同。验证以下内容-1您没有在代码的后面某个点将解析器的委托设置为超类实例。2您已经正确拼写了NSXMLParserDelegate实现,包括类还是实例methods@Nick-你错了。self是指正在创建的实例,如果您测试它的类,它将是您的类。如果您定义了隐藏超类委托方法的委托方法,则委托用户将调用您的方法。你不知怎么搞糊涂了。@HotLicks明白了。我的问题/困惑是为什么执行基类实现而不是子类实现。我认为这是我犯了一个错误的征兆,就像卡尔逃避的那样。我意识到我的帖子有一些不准确的地方,我会很快把它们清理掉。Thanks@Nick在子类的initWith中放置断点。。。以及NSXMLParserDelegate方法的子类和超类实现。在初始值设定项中,注意self、self.parser、self.parser.delegate的地址。在委托方法中,注意self的地址和作为大多数方法的第一个参数传递的解析器实例。