Terminating app due to uncaught exception - iphone

Im parsing an XML with NSXMLParser like say in Apple Developer Documentation.
Im do the parser fine, but when i want put in an NSString the Object parser there is an error, with SIGABRT.
The exception is:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[ClinicasAsociadasProfesionales objectForKey:]: unrecognized selector sent to instance 0x606c8c0'
Im save the objects in te NSMutableArray like:
-(void)parser:(NSXMLParser *)parser
didEndElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI
qualifiedName:(NSString *)qName
{
if([elementName isEqualToString:#"Clinicas"])
{
return;
}
if([elementName isEqualToString:#"Clinica"])
{
[arrayClinicas addObject: varClinicasAsociadasProfesionales];
[varClinicasAsociadasProfesionales release];
}
if([elementName isEqualToString:#"NombreClinica"])
{
[varClinicasAsociadasProfesionales setValue:soapResults forKey:elementName];
}
if([elementName isEqualToString:#"IdClinica"])
{
[varClinicasAsociadasProfesionales setValue:soapResults forKey:elementName];
}
soapResults=nil;
[soapResults release];
elementoEncontrado = NO;
}

crash is not for this code ..somewhere you are using
[ClinicasAsociadasProfesionales objectForKey:]
Instead you should use
[ClinicasAsociadasProfesionales valueForKey:]
as you are using setValue:ForKey: methos to set a value to ClinicasAsociadasProfesionales object

Related

Termination app due to uncaught exception, cannot init a class object

I use SOAP to get Time from website, when executes the following souce code, it raises problem.
I guess the line 4 at below source code has problem, but I don't know how to fix, please help.
Thanks.
Source Code:
-(void) parse:(NSXMLParser *)parser didEndElement:(NSString *) elementName namespaceURI:(NSString *)namespceURI qualifiedName:(NSString *)qName {
if ([elementname isEqualToString:#"getOffesetUTCTimeResult"])
{
greeting.text = [[[NSString init] strinWithFormat:#"The local time is:", nameInput.text] stringByAppending:soapResults];
[soapResults release];
soapResults = nil;
}
}
Raised error:
*** Termination app due to uncaught exception 'NSInvalidArgumentException', reason: '** +[NSString <0x267fd8> init]: cnnot init a class object.'
*** First throw call stack:
...
terminate called throwing an exception
You cannot call the initializer without allocing memory for objects. For NSString, you can do something like:
greeting.text = [[NSString stringWithFormat:#"The local time is:", nameInput.text] stringByAppending:soapResults];
You don't have to init NSString.
Just useĀ 
greeting.text = [[NSString strinWithFormat:#"The local time is:", nameInput.text] stringByAppending:soapResults];

NSArray gives NSZombie error

I am trying to pass a single array object (that is a nsdictionary of several values) back to my main view.
basicly when I set the view up I parse some xml into an array of dictionaries. I then set up my tableview with one of the values inside the NSdictionary, this value is also used to set up the alphabetical scroller and section titles. (this is done in a method I created)
At the end of that method I call [self.tableView reloadData]; every thing loads up perfectly and everything displays fine.
Now what I am trying to do is set it up so that when a cell is selected, I check the value inside the cell.textlabel and use that as a predicate to check against my array of dictionaries once It finds the corresponding entry I want to pass that dictionary up to the main view with a delegate I have made.
however I am getting a error, that I think might be happening due to my reloadData.. but am not sure.
This is what my predicate looks like.
NSPredicate *pred = [NSPredicate predicateWithFormat:#"%K like %#",#"MANUFACTURER",cell.textLabel.text];
NSArray *filter = [myDataArray filteredArrayUsingPredicate:pred]; //error happens here
//check to see if the value is the correct one
NSLog(#"My Filtered array = %#", filter);
//once problem has been found set up the delegate here.
and this is the error message I receive.
2011-10-31 10:43:57.333 code[5812:207] *** -[__NSArrayM filteredArrayUsingPredicate:]: message sent to deallocated instance 0x6874210
myDataArray is created in the NSXMLParser delegates as listed below.
//.h
NSMutableArray *myDataArray;
}
#property (nonatomic, retain) NSMutableArray *myDataArray;
//.m
#pragma mark - Parsing lifecycle
- (void)startTheParsingProcess:(NSData *)parserData
{
//myDataArray = [NSMutableArray arrayWithCapacity:8]; // not even sure if this is needed as its declared later on.
NSXMLParser *parser = [[NSXMLParser alloc] initWithData:parserData]; //parserData passed to NSXMLParser delegate which starts the parsing process
[parser setDelegate:self];
[parser parse]; // starts the event-driven parsing operation.
[parser release];
}
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
if([elementName isEqualToString:#"Row"])
{
manufactureMutableDictionary = [[NSMutableDictionary alloc] initWithDictionary:attributeDict];
}
if([elementName isEqualToString:#"Rows"])
{
myDataArray = [NSMutableArray arrayWithCapacity:8];
}
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
if([elementName isEqualToString:#"Row"])
{
[myDataArray addObject:manufactureMutableDictionary];
}
[manufactureMutableDictionary release];
manufactureMutableDictionary = nil;
}
Any help would be greatly appreciated, also do you think I am going about passing all the values of the dictionary the right way?
You are using an autoreleased array
myDataArray = [NSMutableArray arrayWithCapacity:8];
You have properties set up so use them e.g.
self.myDataArray = [NSMutableArray arrayWithCapacity:8];
or even better
NSMutableArray *tmpMyDataArray = [[NSMutableArray alloc] initWithCapacity:8];
self.myDataArray = tmpMyDataArray;
[tmpMyDataArray release]; tmpMyDataArray = nil;

Parse Nested XML Objective C - NSXMLParser

All,
I have XML in the following format:
<linked-list>
<Description>
<desc></desc>
<IP></IP>
</Description>
</linked-list>
This XML statement could have an infinite number of <Description></Description> inside of the <linked-list></linked-list>.
How should I parse this using NSXMLParser? My current code is as follows, but it parses incorrectly.
#implementation XMLParser
#synthesize response;
- (XMLParser *) initXMLParser
{
self = [super init];
// init dictionary of response data
response = [[NSMutableDictionary alloc] init];
return self;
}
//Gets Start Element of SessionData
- (void)parser:(NSXMLParser *)parser
didStartElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI
qualifiedName:(NSString *)qualifiedName
attributes:(NSDictionary *)attributeDict
{
if ([elementName isEqualToString:#"linked-list"])
{
NSLog(#"Found linked-list in the return XML! Continuing...");
//response is a NSMutableArray instance variable
//THIS SHOULD NEVER NEED TO BE USED
if (!response)//if array is empty, it makes it!
{
NSLog(#"Dictionary is empty for some reason, creating...");
response = [[NSMutableDictionary alloc] init];
}
//END: THIS SHOULD NEVER BE USED
return;
}
else
{
currentElementName = elementName;
NSLog(#"Current Element Name = %#", currentElementName);
return;
}
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
if (!currentElementValue) {
// init the ad hoc string with the value
currentElementValue = [[NSMutableString alloc] initWithString:string];
} else {
[currentElementValue setString:string];
NSLog(#"Processing value for : %#", string);
}
}
//Gets End Element of linked-list
- (void)parser:(NSXMLParser *)parser
didEndElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI
qualifiedName:(NSString *)qName {
if ([elementName isEqualToString:#"linked-list"])
{
// We reached the end of the XML document
// dumps dictionary into log
NSLog(#"Dump:%#", [response description]);
return;
}
else
{
//Adds key and object to dictionary
[response setObject:currentElementValue forKey:currentElementName];
NSLog(#"Set values, going around again... brb.");
}
currentElementValue = nil;
currentElementName = nil;
}
#end
Some observations:
An infinite number of WHAT inside of the WHAT?
Assuming there can be more than one Description element, the outer data structure in which you store the contents must be a NSMutableArray, not a dictionary. You then use one mutable dictionary per Description element.
Consequently, in didStartElement:, check if the element name is #"Description" and if so, create a new NSMutableDictionary instance that you store in an ivar.
In foundCharacters:, you always have to append the new characters to the existing currentElementValue because the method can be called multiple times for each element's contents. I see many people do this wrong despite the fact that Apple's sample code clearly demonstrates the correct way.
In didEndElement:, do this:
If the element name is #"desc" or #"IP", assign currentElementValue to the corresponding key in your current mutable dictionary. Don't forget to release currentElementValue before you set it to nil. You currently have a memory leak in your code because you're not doing that.
If the element name is #"Description", add the current mutable dictionary to the mutable array. Release the dictionary and set the ivar to nil. A new dictionary will be created the next time you encounter a #"Description" element in didStartElement:.
If the element name is #"linked-list", the mutable array will contain all the dictionaries and you're done.

NSXMLParser Parsing RSS into a Custom Object

I have my nsxmlparser parsing the news feed just fine:
http://www.skysports.com/rss/0,20514,12433,00.xml
However when it comes to saving it into my custom object, although I recieve output of each entry in the xml, it only stores one record which happens to be the last one.
Please see my code:
-(void) parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
if ([elementName isEqualToString:#"rss"]) {
currentNews = [[NewsParse alloc] init];
}
}
-(void) parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
if ([elementName isEqualToString:#"description"]) {
currentNews.newsTitle = currentNodeContent;
NSLog(#"description = %#",currentNodeContent);
}
if([elementName isEqualToString:#"rss"])
{
[news addObject:currentNews];
[currentNews release];
currentNews = nil;
[currentNodeContent release];
currentNodeContent = nil;
}
}
This method worked fine with a twitter feed but now i'm assuming because the xml is formed differently I cannot get it to work.
I'm still pretty new to using NSXMLParser so any help would be cool :)
Looking at the RSS feed it appears that you are looking for the wrong tag to begin and end your objects. You need to replace
[elementName isEqualToString:#"rss"]
with
[elementName isEqualToString:#"item"]
in both places.
The way you are doing it now you are looking at the entire page as 1 object. You need to look at each "item" ( <item> </item> ) as an object. The reason why you are successfully getting the last object to save is because you replacing each "description" every time you run through your items. It is replacing the string over and over and over again before you actually save. The last object never gets replaced before saving and therefor the only object you see as saved..
Hmmm, currentNews.newsTitle is changed every time and once it reads the closing rss tag, it has the value of the last feed. What type of object is your currentNews? If you want to keep all different titles, then you have to add them to some sort of object that holds several values, like an array, when you find the closing tag of description simply copy the string for currentNodeContent into an individual instance of news.
I would actually allocate the instance of currentNews in the didEndElement tag outside any comparisson just in case you have more elements to look for. That closing tag probably like this:
-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
if ([elementName isEqualToString:#"title"]) {
self.currentNews.newsTitle = [[NSString alloc] initWithString:currentNodeContent];
}
if ([elementName isEqualToString:#"description"]) {
self.currentNews.newsDescription = [[NSString alloc] initWithString:currentNodeContent];
}
if ([elementName isEqqualToString:#"link"]) {
self.currentNews.newsLink = [[NSString alloc] initWithString:currentNodeContent];
}
if ([elementName isEqualToString:#"guid"]) {
self.currentNews.newsGuid = [[NSString alloc] initWithString:currentNodeContent];
}
if ([elementName isEqualToString:#"pubDate"]) {
self.currentNews.newsPubDate = "probably a date formatter here";
}
if ([elementName isEqualToString:#"cathegory"]) {
self.currentNews.newsCathegory = [[NSString alloc] initWithString:currentNodeContent];
}
blah...
blah...
if ([elementName isEqualToString:#"item"]) {
[news addObject:currentNews];
[self.currentNews.newsTitle release];
[self.currentNews.newsDescription release];
[self.currentNews.newsLink release];
[self.currentNews.newsGuid release];
blah...
blah...
blah...
}
}
And allocate your currentNews object in your init method (remove it from your didStartElement) and release it in your dealloc method. Oh, and #Louie is right, you need to look at your news as an array object which obviously has several currentNews, this currentNews or item is what your parser should be concerned about. After parsing all the element in "just one item" you add it to your news array when it reads the last element tag for that "one item", because after that your parser is simply going to loop and look for the next item.

Memory Leak with NSXMLParser on IPhone

below is my code, Leaks says I am getting a memory leak around NSMutableString alloc method. I am sure it is something I simply overlooked, let me know if anyone has any thoughts. Thanks!
-(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{
if (!currentValue) {
currentValue = [[NSMutableString alloc] initWithCapacity:[string length]];
}
[currentValue setString:[string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]];
}
-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName{
if([elementName isEqualToString:#"phone"]){
currentAgent.phone = currentValue;
}
[currentValue release];
currentValue = nil;
}
-Agent is a custom object that was created when the class was initialized. The XML is valid and has all the appropriate begin/end tags.
Looking over this code, I think it's more likely that your Agent class is leaking phone. Assuming Agent uses retain for the phone property, this will cause the phone to persist longer than it should.
The creator of the object gets "credited" with the leak, even if the extra retain is somewhere else.
In other words, in Agent:
- (void)dealloc {
self.phone = nil;
// anything else you need to do
[super dealloc];
}