Je suis débutant en iOS. J'essaie de créer un lecteur RSS pour un site d'actualités, le parseur RSS est en état de marche mais il donne l'exception EXC_BAD_ACCESS (code=2 address=0xc) s'il est compilé avec ARC activé.
Voici comment j'appelle le parseur : (dans mon contrôleur de vue)
NSMutableArray* articleListMainPage;
- (void)viewDidLoad
{
NSURL *mainFeed = [[NSURL alloc]initWithString:@"http://my.domain.com/rss.xml"];
NSXMLParser *nsXmlParser = [[NSXMLParser alloc] initWithContentsOfURL:mainFeed];
NewsParser *myparser = [[NewsParser alloc] initNewsParser];
[nsXmlParser setDelegate:myparser];
if ([nsXmlParser parse]) {
NSLog(@"Parsed article count : %i", [myparser.articles count]);
articleListMainPage = [myparser.articles copy];
} else {
NSLog(@"Error parsing document!");
}
nsXmlParser = nil;
mainFeed = nil;
myparser = nil; // This line throws the exception.
[super viewDidLoad];
}
et voici le parseur lui-même :
// NewsParser.m
#import "NewsParser.h"
#import "RSSEntry.h"
@implementation NewsParser
@synthesize article, articles, currValue;
- (NewsParser *) initNewsParser
{
if (self = [super init]) return self; else return nil;
}
- (void)parser:(NSXMLParser *)parser
didStartElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI
qualifiedName:(NSString *)qualifiedName
attributes:(NSDictionary *)attributeDict {
if ([elementName isEqualToString:@"channel"]) {
self.articles = [[NSMutableArray alloc] init];
}
if ([elementName isEqualToString:@"item"]) {
self.article = [[ArticleEntry alloc] init];
}
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
if (!currValue) {
self.currValue = [[NSMutableString alloc] initWithString:string];
} else {
[self.currValue appendString:string];
}
}
- (void)parser:(NSXMLParser *)parser
didEndElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI
qualifiedName:(NSString *)qName {
if ([elementName isEqualToString:@"channel"]) {
return;
}
if ([elementName isEqualToString:@"item"]) {
[self.articles addObject:self.article];
self.article = nil;
} else {
if ([[NSArray arrayWithObjects:@"title",@"link",@"description",nil] containsObject:elementName])
[self.article setValue:self.currValue forKey:elementName];
}
self.currValue = nil;
}
@end
//NewsParser.h
#import <Foundation/Foundation.h>
#import "RSSEntry.h"
@interface NewsParser : NSXMLParser <NSXMLParserDelegate> {
NSMutableString *currValue;
NSMutableArray *articles;
ArticleEntry *article;
}
- (NewsParser *) initNewsParser;
@property (nonatomic,retain) ArticleEntry *article;
@property (nonatomic,retain) NSMutableArray *articles;
@property (nonatomic,retain) NSMutableString *currValue;
@end
et la classe que j'utilise pour stocker les entrées RSS.
//RSSEntry.h
#import <Foundation/Foundation.h>
@interface ArticleEntry : NSObject {
NSString *title;
NSString *link;
NSString *description;
}
@property (nonatomic, retain) NSString *title;
@property (nonatomic, retain) NSString *link;
@property (nonatomic, retain) NSString *description;
- (id)initNewArticle:(NSString*)_title url:(NSString*)_link description:(NSString*)_desc;
@end
//RSSEntry.m
#import "RSSEntry.h"
@implementation ArticleEntry
@synthesize title,link,description;
- (id)initNewArticle:(NSString *)_title url:(NSString *)_link description:(NSString *)_desc
{
if ((self = [super init])) {
title = [_title copy];
link = [_link copy];
description = [_desc copy];
return self;
}
else return nil;
}
@end
Comme je l'ai dit, cela fonctionne bien sans ARC, mais je veux savoir si je fais quelque chose que je ne devrais pas faire (par exemple, retenir quelque chose que je ne devrais pas ou ne pas libérer correctement quelque chose/supprimer quelque chose) dans le code.
Merci pour votre temps