我有一个XMLParser类。只要我不删除将节点添加到NSMutableArray的行的注释,它就可以正常工作:
[nodes addObject:self.currentNode];
如果我这样做,应用程序崩溃 - 不会在调试日志中留下任何痕迹。 怎么会这样?
XMLParser.m:
#import "XMLParser.h"
#import "MyViewController.h"
#import "Node.h"
@implementation XMLParser
@synthesize currentNode, currentProperty, currentAddress, nodes;
- (NSMutableArray *)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];
NSLog(@"Proceeded from parser.");
NSLog(@"Returning %@ rows", [nodes count]);
//[parser release];
return self.nodes;
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
if (self.currentProperty) {
[currentProperty appendString:string];
}
}
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict {
if (qName) {
elementName = qName;
}
NSLog(@"<%@>", elementName);
if(self.currentNode)
{
if ([elementName isEqualToString:@"id"] || [elementName isEqualToString:@"name"])
{
self.currentProperty = [NSMutableString string];
}
} 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;
} else if ([elementName isEqualToString:@"node"]) {
NSLog(@"Adding node to array");
//[nodes addObject:self.currentNode];
self.currentNode = nil;
}
}
NSLog(@"</%@>", elementName);
self.currentProperty = nil;
}
- (void) dealloc {
[currentNode release];
[currentAddress release];
[currentProperty release];
[super dealloc];
}
@end
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, retain) NSMutableArray *nodes;
- (NSMutableArray *)parseNodeData:(NSString *)data;
@end
编辑:调试日志的输出
[Session started at 2009-05-26 23:31:26 +0200.]
2009-05-26 23:31:28.352 HelloWorld[6914:20b] <response>
2009-05-26 23:31:28.353 HelloWorld[6914:20b] <nodesearchresult>
2009-05-26 23:31:28.354 HelloWorld[6914:20b] <resultsreturned>
2009-05-26 23:31:28.354 HelloWorld[6914:20b] </resultsreturned>
2009-05-26 23:31:28.354 HelloWorld[6914:20b] <resultsfound>
2009-05-26 23:31:28.354 HelloWorld[6914:20b] </resultsfound>
2009-05-26 23:31:28.355 HelloWorld[6914:20b] <nodes>
2009-05-26 23:31:28.355 HelloWorld[6914:20b] <node>
2009-05-26 23:31:28.356 HelloWorld[6914:20b] Initialized new node...
2009-05-26 23:31:28.356 HelloWorld[6914:20b] <id>
2009-05-26 23:31:28.356 HelloWorld[6914:20b] Tried setting node id: 614
2009-05-26 23:31:28.356 HelloWorld[6914:20b] </id>
2009-05-26 23:31:28.357 HelloWorld[6914:20b] <name>
2009-05-26 23:31:28.357 HelloWorld[6914:20b] Tried setting node name: Roberts coffee
2009-05-26 23:31:28.357 HelloWorld[6914:20b] </name>
2009-05-26 23:31:28.358 HelloWorld[6914:20b] <address>
2009-05-26 23:31:28.358 HelloWorld[6914:20b] <street>
2009-05-26 23:31:28.358 HelloWorld[6914:20b] </street>
2009-05-26 23:31:28.358 HelloWorld[6914:20b] <zipcode>
2009-05-26 23:31:28.359 HelloWorld[6914:20b] </zipcode>
2009-05-26 23:31:28.359 HelloWorld[6914:20b] </address>
2009-05-26 23:31:28.359 HelloWorld[6914:20b] <position>
2009-05-26 23:31:28.359 HelloWorld[6914:20b] <latitude>
2009-05-26 23:31:28.360 HelloWorld[6914:20b] </latitude>
2009-05-26 23:31:28.360 HelloWorld[6914:20b] <longitude>
2009-05-26 23:31:28.360 HelloWorld[6914:20b] </longitude>
2009-05-26 23:31:28.361 HelloWorld[6914:20b] </position>
2009-05-26 23:31:28.361 HelloWorld[6914:20b] <phone>
2009-05-26 23:31:28.361 HelloWorld[6914:20b] </phone>
2009-05-26 23:31:28.363 HelloWorld[6914:20b] <nodetypes>
2009-05-26 23:31:28.363 HelloWorld[6914:20b] <nodetype>
2009-05-26 23:31:28.363 HelloWorld[6914:20b] </nodetype>
2009-05-26 23:31:28.364 HelloWorld[6914:20b] </nodetypes>
2009-05-26 23:31:28.364 HelloWorld[6914:20b] <rating>
2009-05-26 23:31:28.364 HelloWorld[6914:20b] <score>
2009-05-26 23:31:28.365 HelloWorld[6914:20b] </score>
2009-05-26 23:31:28.365 HelloWorld[6914:20b] <votes>
2009-05-26 23:31:28.366 HelloWorld[6914:20b] </votes>
2009-05-26 23:31:28.366 HelloWorld[6914:20b] </rating>
2009-05-26 23:31:28.366 HelloWorld[6914:20b] <teaser>
2009-05-26 23:31:28.367 HelloWorld[6914:20b] </teaser>
2009-05-26 23:31:28.367 HelloWorld[6914:20b] Adding node to array
2009-05-26 23:31:28.367 HelloWorld[6914:20b] </node>
2009-05-26 23:31:28.367 HelloWorld[6914:20b] <node>
2009-05-26 23:31:28.368 HelloWorld[6914:20b] Initialized new node...
2009-05-26 23:31:28.368 HelloWorld[6914:20b] <id>
2009-05-26 23:31:28.368 HelloWorld[6914:20b] Tried setting node id: 326
2009-05-26 23:31:28.368 HelloWorld[6914:20b] </id>
2009-05-26 23:31:28.369 HelloWorld[6914:20b] <name>
2009-05-26 23:31:28.369 HelloWorld[6914:20b] Tried setting node name: Sort kaffe & vinyl
2009-05-26 23:31:28.369 HelloWorld[6914:20b] </name>
2009-05-26 23:31:28.369 HelloWorld[6914:20b] <address>
2009-05-26 23:31:28.370 HelloWorld[6914:20b] <street>
2009-05-26 23:31:28.370 HelloWorld[6914:20b] </street>
2009-05-26 23:31:28.371 HelloWorld[6914:20b] <zipcode>
2009-05-26 23:31:28.371 HelloWorld[6914:20b] </zipcode>
2009-05-26 23:31:28.372 HelloWorld[6914:20b] </address>
2009-05-26 23:31:28.372 HelloWorld[6914:20b] <position>
2009-05-26 23:31:28.372 HelloWorld[6914:20b] <latitude>
2009-05-26 23:31:28.373 HelloWorld[6914:20b] </latitude>
2009-05-26 23:31:28.373 HelloWorld[6914:20b] <longitude>
2009-05-26 23:31:28.373 HelloWorld[6914:20b] </longitude>
2009-05-26 23:31:28.374 HelloWorld[6914:20b] </position>
2009-05-26 23:31:28.374 HelloWorld[6914:20b] <phone>
2009-05-26 23:31:28.375 HelloWorld[6914:20b] </phone>
2009-05-26 23:31:28.375 HelloWorld[6914:20b] <nodetypes>
2009-05-26 23:31:28.375 HelloWorld[6914:20b] <nodetype>
2009-05-26 23:31:28.375 HelloWorld[6914:20b] </nodetype>
2009-05-26 23:31:28.376 HelloWorld[6914:20b] <nodetype>
2009-05-26 23:31:28.376 HelloWorld[6914:20b] </nodetype>
2009-05-26 23:31:28.376 HelloWorld[6914:20b] </nodetypes>
2009-05-26 23:31:28.376 HelloWorld[6914:20b] <rating>
2009-05-26 23:31:28.377 HelloWorld[6914:20b] <score>
2009-05-26 23:31:28.377 HelloWorld[6914:20b] </score>
2009-05-26 23:31:28.377 HelloWorld[6914:20b] <votes>
2009-05-26 23:31:28.377 HelloWorld[6914:20b] </votes>
2009-05-26 23:31:28.378 HelloWorld[6914:20b] </rating>
2009-05-26 23:31:28.378 HelloWorld[6914:20b] <teaser>
2009-05-26 23:31:28.379 HelloWorld[6914:20b] </teaser>
2009-05-26 23:31:28.379 HelloWorld[6914:20b] Adding node to array
2009-05-26 23:31:28.379 HelloWorld[6914:20b] </node>
2009-05-26 23:31:28.380 HelloWorld[6914:20b] </nodes>
2009-05-26 23:31:28.380 HelloWorld[6914:20b] </nodesearchresult>
2009-05-26 23:31:28.381 HelloWorld[6914:20b] </response>
2009-05-26 23:31:28.381 HelloWorld[6914:20b] Proceeded from parser.
[Session started at 2009-05-26 23:31:28 +0200.]
Loading program into debugger…
GNU gdb 6.3.50-20050815 (Apple version gdb-962) (Sat Jul 26 08:14:40 UTC 2008)
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "i386-apple-darwin".warning: Unable to read symbols for "/System/Library/Frameworks/UIKit.framework/UIKit" (file not found).
warning: Unable to read symbols from "UIKit" (not yet mapped into memory).
warning: Unable to read symbols for "/System/Library/Frameworks/CoreLocation.framework/Versions/A/CoreLocation" (file not found).
warning: Unable to read symbols from "CoreLocation" (not yet mapped into memory).
warning: Unable to read symbols for "/System/Library/Frameworks/CoreGraphics.framework/CoreGraphics" (file not found).
warning: Unable to read symbols from "CoreGraphics" (not yet mapped into memory).
Program loaded.
sharedlibrary apply-load-rules all
Attaching to program: `/Users/philipdahlstrm/Library/Application Support/iPhone Simulator/User/Applications/6BD1CC99-F133-4B97-A041-1D210851B6C6/HelloWorld.app/HelloWorld', process 6914.
(gdb)
答案 0 :(得分:3)
您的错误在最终的NSLog中:
NSLog(@"Returning %@ rows", [nodes count]);
%@
获取指向对象的指针。 [nodes count]
返回一个无符号整数,然后将其作为指针取消引用。如果节点为空则没关系,因为-count
返回0,这是nil,这样可以安全地取消引用。您应该使用%d
而不是%@
。
调试器堆栈应该已经显示了发生这种情况的确切位置。我通过查看日志的最后一行并查看之后发生的事情找到了它。
你在这里泄漏了大量的记忆,顺便说一下。如果您使用保留访问者(例如self.nodes =...
)的作业中的Three Magic Words之一,则需要autorelease
。
self.currentNode = [[Node alloc] init];
应该是:
self.currentNode = [[[Node alloc] init] autorelease];
你应该总是使用ivars的访问器。永远不要直接按照您的方式访问节点(除了在他们的访问者和dealloc
中)。