我正在使用NSXMLParser并且我得到一个指向NSConcreteMapTable的内存泄漏,无论是什么:
从AppDelegate.m调用解析器时,此代码行发生泄漏:
我已经找到了一个解决方案,看不出我做错了什么。 这是我的代码。 任何帮助是极大的赞赏。 LQ
// * * * XMLParser.h * * *
#import <Foundation/Foundation.h>
@protocol NSXMLParserDelegate;
@interface XMLParser : NSObject
<NSXMLParserDelegate>
{
NSMutableArray *xmlArray;
BOOL storingCharacters;
float xmlDataVersion;
}
@property (nonatomic, retain) NSMutableArray *xmlArray;
@property (nonatomic) BOOL storingCharacters;
@property (nonatomic, assign) float xmlDataVersion;
-(BOOL)parseXMLFileAtURL:(NSURL *)URL parseError:(NSError **)error;
@end
// * * * XMLParser.m * * *
#import "XMLParser.h"
@implementation XMLParser
@synthesize xmlArray;
@synthesize storingCharacters;
@synthesize xmlDataVersion;
- (BOOL)parseXMLFileAtURL:(NSURL *)URL parseError:(NSError **)error {
BOOL result = YES;
if (xmlArray == nil) {
// this array holds row data extracted from the XML parser didStartElement method
xmlArray = [[NSMutableArray alloc] init];
}
[[NSURLCache sharedURLCache] setMemoryCapacity:0];
[[NSURLCache sharedURLCache] setDiskCapacity:0];
NSXMLParser *parser = [[NSXMLParser alloc] initWithContentsOfURL:URL];
if (parser != nil) {
[parser setDelegate:self];
[parser setShouldProcessNamespaces:NO];
[parser setShouldReportNamespacePrefixes:NO];
[[parser setShouldResolveExternalEntities:NO];
}
[parser parse];
if (parseError && error) {
*error = parseError;
result = NO;
}
[parser release];
return result;
}
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict {
if (qName) {
elementName = qName;
}
// Check the data version of the XML Data against my stored value
if ([elementName isEqualToString:@"data"]) {
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
self.xmlDataVersion = [[attributeDict objectForKey:@"version"] floatValue];
float storedDataVersion = [userDefaults floatForKey:kDataVersion];
if (self.xmlDataVersion <= storedDataVersion) {
// - - - - -> Abort parsing if the same or earlier data versions
[parser abortParsing];
}
}
if ([elementName isEqualToString:@"FirstColumnName"]) {
storingCharacters = YES;
} else if ([elementName isEqualToString:@"SecondColumnName"]) {
storingCharacters = YES;
// ... total of 16 elements
}
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
if (storingCharacters) {
[self.xmlArray addObject:string];
}
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
if (qName) {
elementName = qName;
}
// - - - - -> If at the end of a data row, save changes to object model
if ([elementName isEqualToString:@"ROW"]) {
// - - - - -> Make sure the data has the required number of elements before taking any action
if ([self.xmlArray count] == 16) {
// … //Store or Update Data in SQLite store depending on data values
}
[self.xmlArray removeAllObjects];
}
storingCharacters = NO;
}
-(void)dealloc {
[xmlArray release];
[super dealloc];
}
// * * * AppDelegate.m * * *
#import "XMLParser.h"
@implementation AppDelegate
- (void)applicationDidFinishLaunching:(UIApplication *)application {
NSURL *xmlURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"FileName" ofType:@"xml"]];
NSError *parseError = nil;
XMLParser *xmlParse = [[XMLParser alloc] init];
[xmlParse parseXMLFileAtURL:xmlURL parseError:&parseError];
[xmlParse release];
. . .
}
答案 0 :(得分:6)
我在其他SO帖子中找到了解决方案:
使用:
NSData * dataXml = [[NSData alloc] initWithContentsOfURL:URL];
NSXMLParser *parser = [[NSXMLParser alloc] initWithData:dataXml];
[dataXml release];
而不是:
NSXMLParser *parser = [[NSXMLParser alloc] initWithContentsOfURL:URL];
泄漏消失了。
答案 1 :(得分:0)
这可能是Apple代码中的漏洞,因为Foundation被报告为“负责任的图书馆”。你可能无能为力,只能向苹果报告这个错误。