Утечка памяти при использовании NSXMLParser в NSConcreteMapTable - PullRequest
3 голосов
/ 16 мая 2011

Я использую NSXMLParser и получаю утечку памяти, которая указывает на NSConcreteMapTable, что бы это ни было:

enter image description here

Утечка происходит в этой строке кода при вызове анализатораиз моего AppDelegate.m:

enter image description here

Я искал решение и не вижу, что я делаю неправильно.Вот мой кодЛюбая помощь очень ценится.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];

    . . .

}

Ответы [ 2 ]

6 голосов
/ 17 мая 2011

Я нашел решение в другой SO записи:

Использование:

NSData * dataXml = [[NSData alloc] initWithContentsOfURL:URL];
NSXMLParser *parser = [[NSXMLParser alloc] initWithData:dataXml];
[dataXml release];

Вместо:

NSXMLParser *parser = [[NSXMLParser alloc] initWithContentsOfURL:URL];

Утечка исчезла.

0 голосов
/ 16 мая 2011

Это, вероятно, утечка в коде Apple, поскольку Фонд называется «Ответственная библиотека».Вероятно, вы ничего не можете сделать, кроме как сообщить об ошибке в яблоко.

...