我有以下.xml文件:
<?xml version="1.0" encoding="UTF-8"?>
<company>
<employee>
<id>0</id>
<firstname>Jack</firstname>
<lastname>Johnson</lastname>
<jobtitle>CEO</jobtitle>
<departmentid>0</departmentid>
<parentid>0</parentid>
</employee>
<employee>
<id>1</id>
<firstname>Mik</firstname>
<lastname>Black</lastname>
<jobtitle>Senior Manager</jobtitle>
<departmentid>0</departmentid>
<parentid>0</parentid>
</employee>
<employee>
<id>2</id>
<firstname>Kim<firstname>
<lastname>Friht</lastname>
<jobtitle>Senior Manager</jobtitle>
<departmentid>0</departmentid>
<parentid>0</parentid>
</employee>
...
以下头文件:
#import <Foundation/Foundation.h>
#import "Employee.h"
@interface IdParser : NSObject <NSXMLParserDelegate> {
NSXMLParser *xmlParser;
NSMutableArray *employees;
NSString *currentElement;
Employee *employee;
NSMutableString *tempId, *tempFirstName, *tempLastName, *tempDeptId, *tempJobTitle, *tempParentId;
}
-(NSMutableArray *)getSubordinates:(int)idNumber;
@end
以及以下实现:
#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
我遇到了一个非常奇怪的问题。当我调用在IdParser中实现的start方法时,它会解析所有内容,但是当它到达XML的最后一个节点(父代)时,会发生一些奇怪的事情。
该程序退出,并且我收到以下错误消息:
malloc: *对象0x4b33360错误:释放的对象的校验和不正确-释放后可能已修改了对象。
* 在malloc_error_break中设置一个断点进行调试
当前语言:自动;目前 objective-c
现在没有可用的内存来编程:不安全地调用malloc
奇怪的是,当我删除
[tempParentId release];
行时,程序运行正常。我尝试重新排列XML中的元素,然后再次发生相同的事情:程序在最后一个元素处崩溃。对我而言,这是什么原因,因为我不熟悉Objective-C和iOS,所以我寻求帮助。我猜那里有内存问题,因为删除上面提到的行后程序运行正常。谢谢你的帮助。
佩塔尔
编辑:
正如我所说的,我是Obj-C的新手,对内存管理以及与之相关的所有事情我不太了解,因此我使用此示例来学习和扩展有关它的知识。就是说,您能在建议如何解决此问题之前,先尝试解释造成该错误的确切原因。
编辑2:
有时,当我运行代码时,程序会冻结,而不是上面描述的错误消息,而在控制台中我只会看到:
当前语言:自动;目前 objective-c
(gdb)
这可能是问题所在的线索,因为我正在经历随机行为。
编辑3:
员工类别:
#import <Foundation/Foundation.h>
@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
最佳答案
我建议您启用ARC,这将指示编译器为您编写所有内存管理代码。据我所知,它比大多数经验丰富的Objective-C开发人员做得更好,当然也比新开发人员做得更好。
您需要了解有关ARC的所有信息:http://developer.apple.com/library/ios/#releasenotes/ObjectiveC/RN-TransitioningToARC/_index.html
您可以使用Edit -> Refactor -> Convert to Objective-C ARC…
为现有项目启用它。这将修改项目中的代码以使其与ARC兼容(因此请确保在执行此操作之前创建备份或提交到源代码控制!)。
当心ARC代码将无法在非常旧的iOS版本上运行。不过不应该是一个问题。
关于objective-c - NSXMLParser不解析最后一个节点(可能的内存问题),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8405532/