【发布时间】:2011-12-06 19:22:06
【问题描述】:
我有以下 .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 的最后一个节点(parentid)时,会发生一些奇怪的事情。
程序退出,我收到以下错误消息:
malloc: * 对象 0x4b33360 错误:已释放对象的校验和不正确 - 对象可能在被释放后被修改。 * 在 malloc_error_break 中设置断点进行调试 当前语言:自动;目前客观-c 现在没有可用于编程的内存:调用 malloc 不安全
奇怪的是,当我删除 [tempParentId release]; 行时,程序运行良好。我尝试重新排列 XML 中的元素,但同样的事情再次发生:程序在最后一个元素处崩溃。由于我是 Objective-C 和 iOS 的新手,所以导致问题的原因对我来说毫无意义,所以我正在寻求帮助。我猜某处存在内存问题,因为在我删除上面提到的行后程序运行良好。
感谢您的帮助。
佩塔
编辑:
正如我所说,我是 Obj-C 的新手,我不太了解内存管理以及与之相关的所有内容,因此我使用这个示例来学习和扩展我的知识。也就是说,您能否在建议如何修复它之前尝试解释究竟是什么导致了所描述的错误。
EDIT2:
有时当我运行代码时,程序会冻结,而不是上面描述的错误消息,并且在控制台中我只看到:
当前语言:自动;目前客观-c (gdb)
这可能是问题所在的线索,因为我遇到了随机行为。
EDIT3:
员工类:
#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
【问题讨论】:
-
这就是你的全部代码吗?你确定你没有在其他地方对
tempParentId做任何事情吗? -
这是所有的代码。 tempParentId 在头文件中定义并在实现文件中访问。我已经完整地复制了它们。谢谢
-
有点长镜头,但在发布后立即尝试将
tempParentId设置为nil。我不明白为什么在您的代码中需要这样做,但它被认为是一种很好的做法。 -
@AbhiBeckert:将 tempParentId 设置为 nil 实际上解决了问题:) 但是,我不明白为什么。为什么我不应该将其他变量也设置为 nil ?你能解释一下发生了什么吗?非常感谢
-
一般来说,当你完成一个变量时,你应该将它设置为
nil以防止任何东西试图使用它。但是,如果将其设置为nil解决了问题,那么您的代码中一定有一些严重的错误(我在您发布的内容中没有看到任何错误),您应该尝试找到它。该错误可能是也可能不是内存管理问题... Objective-C 是一种低级语言,您正在处理指针。因此,该错误可能在您的应用中几乎在任何地方出现。这就是我打开 ARC 的原因,所以我从来没有这样的头痛。您应该将其他设置为nil。
标签: objective-c ios nsxmlparser