I've been putting on with a strange issue in my iPhone program for a while.
To make long story short: I have an XML which contains data about tree-like composition. I've wrote a parser which constructs a tree from the XML.
Somewhere in DataSource class I have following method:
- (id)loadAllData {
if (self.doc != nil) {
GDataXMLElement *root = [self.doc rootElement];
Component *component = [Component componentWithRoot:root];
NSLog(@"%@", component);
return component;
}
return nil;
}
Factory method looks like this:
+ (id)componentWithRoot:(GDataXMLNode*)element {
id<iComponent> component = nil;
NSString *clsName = [NSString stringWithFormat:@"%@Element", [element name]];
// Will return instance of a class or |nil| if class is not loaded.
Class cls = NSClassFromString(clsName);
if (cls != nil) {
component = [[cls alloc] init];
// dies on next line
NSLog(@"created %@", component);
// Seems that we have corresponding model class
if (component != nil) {
//... setting attrubutes for this model
//... trying to find child elements and add them to the component instance.
}
}
return component;
}
Also when I stop GDB on line where I call alloc and init methods and try to call them in debugger I see next error log:
(gdb) po component
Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_INVALID_ADDRESS at address: 0x828282df
0x01052a67 in objc_msgSend ()
The program being debugged was signaled while in a function called from GDB.
GDB has restored the context to what it was before the call.
To change this behavior use "set unwindonsignal off"
Evaluation of the expression containing the function (_NSPrintForDebugger) will be abandoned.
So the situation is: somehow my program starts up and displays values that I need correctly. But when I try to do something with my component, program just crashes. Any ideas? How can I find a error? I don't any reasons why NSLog(@"created %@", component); crashes application and so do other actions with component (actually I want to encode it to an archive).
Thanks in advance!
Update
This is piece of factory method code with comments
+ (id)componentWithRoot:(GDataXMLNode*)element {
id<iComponent> component = nil;
NSString *clsName = [NSString stringWithFormat:@"%@Element", [element name]];
NSLog(@"%@", clsName);
// Will return instance of a class or |nil| if class is not loaded.
Class cls = NSClassFromString(clsName);
if (cls != nil) {
component = [[[cls alloc] init] autorelease];
// Seems that we have corresponding model class
if (component != nil) {
[component setTitle:[element name]];
/*
when I run app I have first element named ConfigElement.
Code runes fine to this point and even properties are set correct.
But if I set breakpoint at this line and type in consle
po component
I get message which is posted below
*/
(gdb) po component
Program received signal EXC_BAD_ACCESS, Could not access memory. Reason: KERN_INVALID_ADDRESS at address: 0x828282df 0x01052a67 in objc_msgSend () The program being debugged was signaled while in a function called from GDB. GDB has restored the context to what it was before the call. To change this behavior use "set unwindonsignal off" Evaluation of the expression containing the function (_NSPrintForDebugger) will be abandoned.
Since this happens I want to make sure that all init methods are correct. Here what I am doing:
first - check that name of class is ConfigElement - yes
second - look at ConfigElement init - everything ok:
- (id)init {
self = [super init];
return self;
}
third - look at super (Composite) initializer:
- (id)init {
if ((self = [super init])) {
children_ = [[NSMutableArray alloc] init];
}
return self;
}
then look for super initializer again (Component initializer now) - seems good again:
- (id)init {
if ((self=[super init])) {
title_ = nil;
name_ = nil;
icon_ = nil;
parent_ = nil;
children_ = nil;
}
return self;
}
Since Component is a subclass of NSObject I don't need to bother about super initializer again and could probably remove if statement but let it be. Also all these initilizers are designated and they are actually called at the moment of init.
So why I am getting that error msg in GDB?
NSLog(@"component %@", cls)after thecls != nilline? Also, why are you using this rather than the built in serialization/archiving tools?clsNamewas set correctly,clsalso is notnull. And when I docls allocnothing but correct pointer should be returned, am I right?initmethod in the classes thatComponentinstantiates? Are you definately returningselffrom the init method? Does it work if you hard-code in the name of a class you are trying to instantiate? I'd be interested in seeing theinitmethod of a class you are trying to instantiate that fails.descriptionmethod on your object, either viaNSLogor the GDBpo, I don't suppose you've overridedescriptionin yourComponentclass heirarchy? I'll download your source and have a look.