Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

fiskah

macrumors newbie
Original poster
Nov 6, 2008
27
0
Hi there - I am new to iPhone development - and programming where I have to do the memory management myself :)

I've created a class in which I try to parse some XML. In this class I have a property called "currentNode" holding a Node object. However, when I try to manipulate the properties of this object, for example "self.currentNode.nodeId = self.currentProperty;" I get NSInvalidArgumentException. I figure this might have something to do with memory management, but I am not sure.

Can anyone tell me why this exception is thrown? Thanks in advance :D

My code is below.

XMLParser.h
Code:
#import <UIKit/UIKit.h>
#import "Address.h"
#import "Node.h"

@class XMLAppDelegate;

@interface XMLParser : NSObject {
	NSMutableString *currentProperty;
	Address *currentAddress;
	Node *currentNode;
	NSMutableArray *nodes;
}

@property (nonatomic, retain) NSMutableString *currentProperty;
@property (nonatomic, retain) Address *currentAddress;
@property (nonatomic, retain) Node *currentNode;
@property (nonatomic, readwrite) NSMutableArray *nodes;

- (void)parseNodeData:(NSString *)data;

@end

XMLParser.m
Code:
#import "XMLParser.h"
#import "MyViewController.h"
#import "Node.h"


@implementation XMLParser
@synthesize currentNode, currentProperty, currentAddress, nodes;


- (void)parseNodeData:(NSString *)url {
	NSURL *urlObj = [[NSURL alloc] initWithString:url];
	NSXMLParser *parser = [[NSXMLParser alloc] initWithContentsOfURL:urlObj];

    self.nodes = [[NSMutableArray alloc] init];
	
    [parser setDelegate:self];
    [parser setShouldProcessNamespaces:NO];
    [parser setShouldReportNamespacePrefixes:NO];
    [parser setShouldResolveExternalEntities:NO];
    [parser parse];
    [parser release];
}

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
    if (self.currentProperty) {
        [currentProperty appendString:string];
		NSLog(@"foundCharacters called: %@", string);
    }
}

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict {
	if (qName) {
        elementName = qName;
    }
	
	if(self.currentNode)
	{
		if ([elementName isEqualToString:@"id"] || [elementName isEqualToString:@"name"])
		{
			self.currentProperty = [NSMutableString string];
		} else {
			// We're at the end of the node
			self.currentNode = nil;
		}
	} else {
		// We are outside of everything, so we need a
        // Check for deeper nested node
        if ([elementName isEqualToString:@"node"]) {
            self.currentNode = [[Node alloc] init];
			NSLog(@"Initialized new node...");
        }
    }
}

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
	if(self.currentNode)
	{
		if ([elementName isEqualToString:@"id"]) {
			NSLog(@"Tried setting node id: %@", self.currentProperty);
			// self.currentNode.nodeId = self.currentProperty;
			
		} else if ([elementName isEqualToString:@"name"]) {
			NSLog(@"Tried setting node name: %@", self.currentProperty);
			// self.currentNode.name = self.currentProperty;
		}
	}
	
	self.currentProperty = nil;
}

- (void) dealloc {
	
	[super dealloc];
}


@end

Node.h
Code:
//
#import <Foundation/Foundation.h>
#import "Address.h"


@interface Node : NSObject {
	NSInteger *nodeId;
	NSString *name;
	Address *address;
	NSString *teaser;
	NSString *rating;
}

@property (nonatomic, retain) NSMutableString *nodeId;
@property (nonatomic, retain) NSMutableString *name;
@property (nonatomic, retain) Address *address;
@property (nonatomic, retain) NSMutableString *teaser;
@property (nonatomic, retain) NSMutableString *rating;


@end
 
Code:
@interface Node : NSObject {
	NSInteger *nodeId;
	...
}

@property (nonatomic, retain) NSMutableString *nodeId;
...
Is nodeId an NSInteger or an NSMutableString?

P.S. Some of your other Node properties have mismatched types as well.
 
Code:
@interface Node : NSObject {
	NSInteger *nodeId;
	...
}

@property (nonatomic, retain) NSMutableString *nodeId;
...
Is nodeId an NSInteger or an NSMutableString?

P.S. Some of your other Node properties have mismatched types as well.

I see. Wonder why the compiler didn't whine though :)

I've corrected the type mismatches (that I could see) so that Node.h looks like this now:

Code:
#import <Foundation/Foundation.h>
#import "Address.h"


@interface Node : NSObject {
	NSMutableString *nodeId;
	NSMutableString *name;
	Address *address;
	NSMutableString *teaser;
	NSMutableString *rating;
}

@property (nonatomic, retain) NSMutableString *nodeId;
@property (nonatomic, retain) NSMutableString *name;
@property (nonatomic, retain) Address *address;
@property (nonatomic, retain) NSMutableString *teaser;
@property (nonatomic, retain) NSMutableString *rating;


@end

However I still get this exception:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[Node setNodeId:]: unrecognized selector sent to instance 0x47d2e0'
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.