在NSConcreteMapTable中使用NSXMLParser进行内存泄漏 [英] Memory Leak Using NSXMLParser in NSConcreteMapTable

查看:193
本文介绍了在NSConcreteMapTable中使用NSXMLParser进行内存泄漏的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用NSXMLParser,并且出现内存泄漏,它指向NSConcreteMapTable,无论是什么:

I'm using NSXMLParser and I get a memory leak that points to NSConcreteMapTable, whatever that is:

从我的AppDelegate.m调用解析器时,此代码行会发生泄漏:

The leak occurs at this line of code when calling the parser from my AppDelegate.m:

我正在寻找解决方案,但看不到我在做什么错. 这是我的代码. 任何帮助是极大的赞赏. lq

I have searched for a solution and can't see what I'm doing wrong. Here is my code. Any help is greatly appreciated. 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];

    . . .

}

推荐答案

我在另一个使用:

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

代替:

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

泄漏消失了.

这篇关于在NSConcreteMapTable中使用NSXMLParser进行内存泄漏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆