Note that there are some explanatory texts on larger screens.

plurals
  1. PONSXMLParser does not parse last node (possible memory issue)
    text
    copied!<p>I have the following .xml file :</p> <pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt; &lt;company&gt; &lt;employee&gt; &lt;id&gt;0&lt;/id&gt; &lt;firstname&gt;Jack&lt;/firstname&gt; &lt;lastname&gt;Johnson&lt;/lastname&gt; &lt;jobtitle&gt;CEO&lt;/jobtitle&gt; &lt;departmentid&gt;0&lt;/departmentid&gt; &lt;parentid&gt;0&lt;/parentid&gt; &lt;/employee&gt; &lt;employee&gt; &lt;id&gt;1&lt;/id&gt; &lt;firstname&gt;Mik&lt;/firstname&gt; &lt;lastname&gt;Black&lt;/lastname&gt; &lt;jobtitle&gt;Senior Manager&lt;/jobtitle&gt; &lt;departmentid&gt;0&lt;/departmentid&gt; &lt;parentid&gt;0&lt;/parentid&gt; &lt;/employee&gt; &lt;employee&gt; &lt;id&gt;2&lt;/id&gt; &lt;firstname&gt;Kim&lt;firstname&gt; &lt;lastname&gt;Friht&lt;/lastname&gt; &lt;jobtitle&gt;Senior Manager&lt;/jobtitle&gt; &lt;departmentid&gt;0&lt;/departmentid&gt; &lt;parentid&gt;0&lt;/parentid&gt; &lt;/employee&gt; ... </code></pre> <p>The following header file:</p> <pre><code>#import &lt;Foundation/Foundation.h&gt; #import "Employee.h" @interface IdParser : NSObject &lt;NSXMLParserDelegate&gt; { NSXMLParser *xmlParser; NSMutableArray *employees; NSString *currentElement; Employee *employee; NSMutableString *tempId, *tempFirstName, *tempLastName, *tempDeptId, *tempJobTitle, *tempParentId; } -(NSMutableArray *)getSubordinates:(int)idNumber; @end </code></pre> <p>And the following implementation:</p> <pre><code>#import "IdParser.h" #import "Employee.h" @implementation IdParser - (void)start{ NSString *file = @"/users/localadmin/Desktop/employeeData.xml"; NSFileManager *filemgr = [NSFileManager defaultManager]; NSData *dataBuffer = [filemgr contentsAtPath: file]; xmlParser = [[NSXMLParser alloc] initWithData:dataBuffer]; [xmlParser setDelegate:self]; [xmlParser parse]; } - (void) parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict{ [currentElement release]; currentElement = [elementName copy]; if([elementName isEqualToString:@"employee"]){ employee = [[Employee alloc]init]; } if([elementName isEqualToString:@"id"]){ tempId = [[NSMutableString alloc]init ]; } if([elementName isEqualToString:@"firstname"]){ tempFirstName = [[NSMutableString alloc]init ]; } if([elementName isEqualToString:@"lastname"]){ tempLastName = [[NSMutableString alloc]init ]; } if([elementName isEqualToString:@"jobtitle"]){ tempJobTitle = [[NSMutableString alloc]init ]; } if([elementName isEqualToString:@"departmentid"]){ tempDeptId = [[NSMutableString alloc]init ]; } if([elementName isEqualToString:@"parentid"]){ tempParentId = [[NSMutableString alloc]init]; } } - (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{ if([currentElement isEqualToString:@"id"]){ [tempId appendString:string]; } if([currentElement isEqualToString:@"firstname"]){ [tempFirstName appendString:string]; } if([currentElement isEqualToString:@"lastname"]){ [tempLastName appendString:string]; } if([currentElement isEqualToString:@"jobtitle"]){ [tempJobTitle appendString:string]; } if([currentElement isEqualToString:@"departmentid"]){ [tempDeptId appendString:string]; } if([currentElement isEqualToString:@"parentid"]){ [tempParentId appendString:string]; } } -(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName{ if([elementName isEqualToString:@"employee"]){ [employee setIdNumber:[tempId intValue]]; [tempId release]; [employee setFirstName:tempFirstName]; [tempFirstName release]; [employee setLastName:tempLastName]; [tempLastName release]; [employee setJobTitle:tempJobTitle]; [tempJobTitle release]; [employee setDepartmentIdNumber:[tempDeptId intValue]]; [tempDeptId release]; [employee setParentIdNumber:[tempParentId intValue]]; [tempParentId release]; //IF I REMOVE THIS LINE, THE PROGRAM DOES NOT CRASH [employees addObject:employee]; [employee release]; } } @end </code></pre> <p>I am experiencing a very strange problem with it. When I am to call the start method implemented in IdParser, it parses everything but when it gets to the last node of the XML (parentid), something strange happens. </p> <p>The program quits and I receive the following error message:</p> <p>malloc: <strong>* error for object 0x4b33360: incorrect checksum for freed object - object was probably modified after being freed. *</strong> set a breakpoint in malloc_error_break to debug Current language: auto; currently objective-c No memory available to program now: unsafe to call malloc </p> <p>Strangely, when I remove the <code>[tempParentId release];</code> line, the program runs fine. I have tried rearranging the elements in the XML and the same thing happens again: the program crashes at the last element. It does no make sense to me what is causing the problem as I am new to Objective-C and iOS so I am asking for help. I guess there is a memory problem somewhere because the program runs fine after I remove the line that I mentioned above.</p> <p>Thanks for any help.</p> <p>Petar</p> <p>EDIT: </p> <p>As I said I am new to Obj-C and I don't understand much about memory management and all the things connected with it so I am using this example to learn and expand my knowledge about it. That said, can you please try to explain what exactly is causing the error described before suggesting how to fix it. </p> <p>EDIT2:</p> <p>Sometimes when I run the code, instead of the error message which I described above, the program freezes and in the console I see just:</p> <p>Current language: auto; currently objective-c (gdb) </p> <p>This may be a clue as to what the problem is because I am experiencing random behaviour.</p> <p>EDIT3:</p> <p>Employee class:</p> <pre><code>#import &lt;Foundation/Foundation.h&gt; @interface Employee : NSObject { int idNumber; NSString *firstName; NSString *lastName; int departmentIdNumber; NSString *jobTitle; int parentIdNumber; } -(id)initWithIdNumber:(int)idValue firstName:(NSString *)firstNameValue lastName:(NSString *)lastNameValue departmentIdNumber:(int)departmentIdNumberValue jobTitle:(NSString *)jobTitleValue parentIdNumber:(int)parentIdNumberValue; @property(nonatomic) int idNumber; @property(nonatomic, retain) NSString *firstName; @property(nonatomic, retain) NSString *lastName; @property(nonatomic, retain) NSString *jobTitle; @property(nonatomic) int departmentIdNumber; @property(nonatomic) int parentIdNumber; @end #import "Employee.h" @implementation Employee @synthesize idNumber, firstName, lastName, departmentIdNumber, jobTitle, parentIdNumber; -(id)initWithIdNumber:(int)idValue firstName:(NSString *)firstNameValue lastName:(NSString *)lastNameValue departmentIdNumber:(int)departmentIdNumberValue jobTitle:(NSString *)jobTitleValue parentIdNumber:(int)parentIdNumberValue{ self = [super init]; if(self){ [self setIdNumber:idValue]; [self setFirstName:firstNameValue]; [self setLastName:lastNameValue]; [self setDepartmentIdNumber:departmentIdNumberValue]; [self setJobTitle:jobTitleValue]; [self setParentIdNumber:parentIdNumberValue]; } return self; } -(NSString *) description{ NSString *desc = [[NSString alloc]initWithFormat:@"ID: %d, firstname: %@, lastname: %@, departmentID: %d, jobtitle: %@, parentID: %d", idNumber, firstName, lastName, departmentIdNumber, jobTitle, parentIdNumber]; return desc; } @end </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload