PDA

View Full Version : NSInvalidArgumentException when trying to edit object properties




fiskah
May 26, 2009, 11:35 AM
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

#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
#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
//
#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



dejo
May 26, 2009, 11:40 AM
@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.

fiskah
May 26, 2009, 11:48 AM
@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:

#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'

BlackWolf
May 26, 2009, 11:52 AM
did you synthesize nodeId?

fiskah
May 26, 2009, 12:10 PM
did you synthesize nodeId?

Doh :) I did now and it worked :) Thanks!