XML解析转到EXC_BAD_ACCESS代码1地址0x10

时间:2015-07-05 14:38:53

标签: ios objective-c xml memory-management xml-parsing

所以这就是事情。我没有以前的手动内存管理经验,正在尝试构建 no-ARC / no-Storyboard 项目。 完整源代码here。 所以我在这里得到的是

类,它帮助我使用自定义初始化程序

创建Products对象

Products.h

@interface Products : NSObject

@property (nonatomic,retain)NSString *productName;
@property (nonatomic,retain)NSString *productDescription;
@property (nonatomic,retain)NSString *productImage;

-(id) initWithName: (NSString *) name
       description: (NSString *) description
             image: (NSString *) image;

@end

Products.m

@implementation Products

-(id) initWithName:(NSString *)name description:(NSString *)description image:(NSString *)image {
self = [super init];

if (self) {
    self.productName = name;
    self.productDescription = description;
    self.productImage = image;
}
return self;

@end

在那里你可以看到ProductParser类,其中包含大部分魔法

ProductsParser.h

@interface ProductsParser : NSObject <NSXMLParserDelegate>

@property (nonatomic,retain) NSMutableArray *productArray;

-(id) initWithArray:(NSMutableArray *) productArray;
-(void) parseXMLFile;

@end

ProductParser.m

    // Creating private properties
@interface ProductsParser()
@property NSXMLParser *parser;
@property NSString *element;

@property NSMutableString *currentProductName;
@property NSMutableString *currentProductDescription;
@property NSMutableString *currentProductImage;

@end



@implementation ProductsParser
-(id) initWithArray:(NSMutableArray *)productArray {
    self = [super init];
    if (self) {
        self.productArray = productArray;
    }
    return self;
}

-(void) parseXMLFile {
    // We will do it here instead of writing that in viewDidLoad
    NSURL *xmlPath = [[NSBundle mainBundle]URLForResource:@"productsList" withExtension:@"xml" ];
    self.parser = [[NSXMLParser alloc]initWithContentsOfURL:xmlPath];
    self.parser.delegate = self;
    [self.parser parse];
    [self.parser release];
}

-(void) parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict {
    self.element = elementName;
}

-(void) parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
    string = [string stringByReplacingOccurrencesOfString:@"\n" withString:@""];
    string = [string stringByReplacingOccurrencesOfString:@"\t" withString:@""];
    string = [string stringByReplacingOccurrencesOfString:@"  " withString:@""];

    if ([self.element isEqualToString:@"Name"]) {
        if (self.currentProductName == nil) {
            self.currentProductName = [[NSMutableString alloc] initWithString:string];
        } else {
            [self.currentProductName appendString:string];
        }
    }
    if ([self.element isEqualToString:@"Description"]) {
        if (self.currentProductDescription == nil) {
            self.currentProductDescription = [[NSMutableString alloc] initWithString:string];
        } else {
            [self.currentProductDescription appendString:string];
        }
    }    if ([self.element isEqualToString:@"Image"]) {
        if (self.currentProductImage == nil) {
            self.currentProductImage = [[NSMutableString alloc] initWithString:string];
        } else {
            [self.currentProductImage appendString:string];
        }
    }
}

-(void) parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
    if ([elementName isEqualToString:@"Product"]) {
        Products *thisProduct = [[Products alloc] initWithName:self.currentProductName description:self.currentProductDescription image:self.currentProductImage];

        [self.productArray addObject:thisProduct];


        [self.currentProductName release];
        self.currentProductName = nil;


        [self.currentProductDescription release];
        self.currentProductDescription = nil;


        [self.currentProductImage release];
        self.currentProductImage = nil;


        [thisProduct release];
        thisProduct = nil;


        [self.element release];
        self.element = nil;
    }
}

@end

稍后,在我想要处理我正在创建的UITableView的类中:

@property (retain,nonatomic)NSMutableArray *productArray;

在viewDidLoad中我们有这段代码

self.productArray = [[NSMutableArray alloc] init];
ProductsParser *menuParser = [[ProductsParser alloc] initWithArray:self.productArray];
[menuParser parseXMLFile];
[menuParser release];

所有这些导致EXC_BAD_ACCESS指向

@property (nonatomic,retain)NSString *productName;

我对这个错误进行了一些研究。用户声称他们通过简单地使用self调用属性来成功摆脱该错误。语法。(假设增加保留计数?)在我的情况下,这不是问题,你可能会看到。(或者我错过了什么?)

我也可以在调试器中看到,假设用.xml文件填充我的产品的productArray实际上填充了垃圾内容,如@“/ n / t”@“/ n”@“/ n / t“等等。(为什么为什么?!)

所以至少要指向我,从哪里开始。非常感谢你的帮助。

UPDATE 1 :显然存在一些缺陷逻辑,我几乎通过更改foundCharacters部分中的代码来摆脱\ n \ t \ t \ n的东西。 所以现在而不仅仅是\ n \ t \ n \ n \ t我在我的数组中得到了实际的数据。像这样:

@"Box of chocolate \n\t\t"
@"Box of chocolate, very tasty \n"
@"ImageName \n\t"

我知道\ n应该像新行一样,\ t显然是制表。但是,对于如何完全摆脱这些以及它们为什么会弹出来没有明确的想法。

UPDATE 2 :我设法通过添加stringByReplacingOccurrencesOfString来摆脱数组中的垃圾\ n \ t。 (代码更新)

0 个答案:

没有答案