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的地址和作为大多数方法的第一个参数传递的解析器实例。