Reputation: 9462
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?
Upvotes: 2
Views: 654
Reputation: 9462
The problem was in my buggy description
method:
- (NSString*)description {
NSString *desc = [NSString stringWithFormat:@"Title: %@, Name: %@, Icon: %@, parent: %@, children: %@", self.title, self.name, self.icon, self.parent];
return desc;
}
Once this method was fixed, debugger started to print correct values.
Upvotes: 2
Reputation: 162722
Both componentWithRoot:
and loadAllData
should be returning an autorelease
d object.
What toiletseat said are all good suggestions/questions. This sounds specifically like a problem internal to your Component
class. Would have to see its innards to say more.
Upvotes: 0