【发布时间】:2011-02-21 09:33:09
【问题描述】:
我正在构建一个解析 rss 提要的应用程序。在应用程序中有两种不同类型的提要,提要中的元素具有不同的名称,因此我创建了一个 NSXMLParser NSObject,它在解析之前获取每个提要的元素名称。这是我的代码:
NewsFeedParser.h
#进口 @interface NewsFeedParser : NSObject { NSInteger NewsSelectedCategory; NSXMLParser *NSXMLNewsParser; NSMutableArray *newsCategories; NSMutableDictionary *NewsItem; NSMutableString *NewsCurrentElement, *NewsCurrentElement1, *NewsCurrentElement2, *NewsCurrentElement3; NSString *NewsItemType, *NewsElement1, *NewsElement2, *NewsElement3; NSInteger NewsNumElements; } - (void) parseXMLFileAtURL:(NSString *)URL; @property(nonatomic, 保留) NSString *NewsItemType; @property(nonatomic, 保留) NSString *NewsElement1; @property(nonatomic, 保留) NSString *NewsElement2; @property(nonatomic, 保留) NSString *NewsElement3; @property(nonatomic, 保留) NSMutableArray *newsCategories; @property(assign, nonatomic) NSInteger NewsNumElements; @结尾NewsFeedParser.m
#import "NewsFeedParser.h" @implementation NewsFeedParser @synthesize NewsItemType; @synthesize NewsElement1; @synthesize NewsElement2; @synthesize NewsElement3; @synthesize 新闻类别; @synthesize NewsNumElements; - (void)parserDidStartDocument:(NSXMLParser *)parser{ } - (void)parseXMLFileAtURL:(NSString *)URL { newsCategories = [[NSMutableArray alloc] init]; URL = [URL stringByReplacingOccurrencesOfString:@" " withString:@""]; URL = [URL stringByReplacingOccurrencesOfString:@"\n" withString:@""]; URL = [URL stringByReplacingOccurrencesOfString:@" " withString:@""]; //然后你必须将路径转换为正确的 NSURL 否则它将不起作用 NSURL *xmlURL = [NSURL URLWithString:URL]; // 这里,由于某种原因,你必须在尝试分配 NSXMLParser 时使用 NSClassFromString,否则你会得到一个 object not found 错误 // 这可能仅对工具链是必需的 [[NSURLCache sharedURLCache] setMemoryCapacity:0]; [[NSURLCache sharedURLCache] setDiskCapacity:0]; NSXMLNewsParser = [[NSXMLParser alloc] initWithContentsOfURL:xmlURL]; // 将 self 设置为解析器的委托,以便接收解析器委托方法回调。 [NSXMLNewsParser setDelegate:self]; // 根据您正在解析的 XML 文档,您可能希望启用 NSXMLParser 的这些功能。 [NSXMLNewsParser setShouldProcessNamespaces:NO]; [NSXMLNewsParser setShouldReportNamespacePrefixes:NO]; [NSXMLNewsParser setShouldResolveExternalEntities:NO]; [NSXMLNewsParser 解析]; [NSXMLNewsParser 发布]; } - (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError { NSString * errorString = [NSString stringWithFormat:@"无法从网站下载故事源(错误代码 %i )", [parseError code]]; NSLog(@"解析 XML 时出错:%@", errorString); UIAlertView * errorAlert = [[UIAlertView alloc] initWithTitle:@"加载内容时出错" message:errorString delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil]; [错误警报显示]; [错误警报发布]; [错误字符串释放]; } - (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURIqualifiedName:(NSString *)qName 属性:(NSDictionary *)attributeDict{ NewsCurrentElement = [元素名称副本]; if ([elementName isEqualToString:NewsItemType]) { // 清除我们的故事项目缓存... NewsItem = [[NSMutableDictionary alloc] init]; NewsCurrentElement1 = [[NSMutableString alloc] init]; NewsCurrentElement2 = [[NSMutableString alloc] init]; 如果(NewsNumElements == 3) { NewsCurrentElement3 = [[NSMutableString alloc] init]; } } } - (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURIqualifiedName:(NSString *)qName{ if ([elementName isEqualToString:NewsItemType]) { // 将值保存到一个项目中,然后将该项目存储到数组中... [NewsItem setObject:NewsCurrentElement1 forKey:NewsElement1]; [NewsItem setObject:NewsCurrentElement2 forKey:NewsElement2]; 如果(NewsNumElements == 3) { [NewsItem setObject:NewsCurrentElement3 forKey:NewsElement3]; } [newsCategories addObject:[[NewsItem copy] autorelease]]; [NewsCurrentElement 发布]; [NewsCurrentElement1 发布]; [NewsCurrentElement2 发布]; 如果(NewsNumElements == 3) { [NewsCurrentElement3 发布]; } [新闻项目发布]; } } - (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string { //NSLog(@"找到的字符:%@", string); // 保存当前项目的字符... if ([NewsCurrentElement isEqualToString:NewsElement1]) { [NewsCurrentElement1 appendString:string]; } else if ([NewsCurrentElement isEqualToString:NewsElement2]) { [NewsCurrentElement2 appendString:string]; } else if (NewsNumElements == 3 && [NewsCurrentElement isEqualToString:NewsElement3]) { [NewsCurrentElement3 appendString:string]; } } - (无效)dealloc { [超级释放]; 【新闻分类发布】; [NewsItemType 发布]; [NewsElement1 发布]; [NewsElement2 发布]; [NewsElement3 发布]; }当我创建类的实例时,我会这样做:
NewsFeedParser *categoriesParser = [[NewsFeedParser alloc] init]; 如果(newsCat == 0) { categoriesParser.NewsItemType = @"article"; categoriesParser.NewsElement1 = @"category"; categoriesParser.NewsElement2 = @"catid"; } 别的 { categoriesParser.NewsItemType = @"article"; categoriesParser.NewsElement1 = @"category"; categoriesParser.NewsElement2 = @"feedUrl"; } [categoriesParser parseXMLFileAtURL:feedUrl]; newsCategories = [[NSMutableArray alloc] initWithArray:categoriesParser.newsCategories copyItems:YES]; [self.tableView reloadData]; [类别解析器发布];如果我使用泄漏工具运行应用程序,则泄漏指向 NewsFeedParser.m 中的 [NSXMLNewsParser parse] 调用。
这是泄漏仪器的屏幕截图,其中 NSCFStrings 泄漏:
http://img139.imageshack.us/img139/3997/leaks.png
在我的一生中,我无法弄清楚这些泄漏是从哪里来的。任何帮助将不胜感激。
【问题讨论】:
标签: iphone memory-leaks nsstring nsxmlparser