【问题标题】:Leak occur at the time of Parsing解析时发生泄漏
【发布时间】:2011-09-15 06:31:51
【问题描述】:

我实际上是在程序开始时进行解析,这是我找到的 parser.m 类 此类中的“泄漏”在方法“foundCharacters”中

currentElementValue = [[NSMutableString alloc] initWithString:string];

currentElementValue 是在 parser.h 文件中声明的 NSMutableString

NSMutableString *currentElementValue;

任何人都可以建议我解决此泄漏的方法,该泄漏有时会在启动时使我的应用程序崩溃...

提前致谢...

didStartElement 方法:-

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName 
  namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName 
    attributes:(NSDictionary *)attributeDict {
    if([elementName isEqualToString:@"posts"]) {
        appDelegate.newsArray = [[NSMutableArray alloc] init];
    }
    else
    {
        if([elementName isEqualToString:@"page"])
        {

            aNewsInfo = [[NewsInfo alloc] init];
            aNewsInfo.page = [[attributeDict objectForKey:@"id"] integerValue];

        }


        if(![elementName compare:@"smallimage"])
        {
            currentElementValue = [NSMutableString string];

        }
        if(![elementName compare:@"largeimage"])
        {
            currentElementValue = [NSMutableString string];
        }
    }
    NSLog(@"Processing Element :%@",elementName);
}

在这个 foundCharacter 方法中发现泄漏:- in line....

currentElementValue = [[NSMutableString alloc] initWithString:string];

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string { 
    if(!currentElementValue) 
        currentElementValue = [[NSMutableString alloc] initWithString:string];
    else
        [currentElementValue appendString:string];

    NSLog(@"Processing Value: %@", currentElementValue);
}

didEndElement 方法:-

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName 
  namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
    if([elementName isEqualToString:@"posts"])
        return;
    if([elementName isEqualToString:@"page"]) {
        [appDelegate.newsArray addObject:aNewsInfo];
        NSLog(@"%d",[appDelegate.newsArray count]);
        NSLog(@"%@",aNewsInfo.title);
        NSLog(@"%@",aNewsInfo.fulltext);
        [aNewsInfo release];
        aNewsInfo = nil;
    }
    else {
        if ([elementName isEqualToString:@"smallimage"])
        {
            NSURL *url = [NSURL URLWithString:currentElementValue];
            NSData *data = [NSData dataWithContentsOfURL:url];
            UIImage *image = [[UIImage alloc] initWithData:data]; 
            [aNewsInfo setSmallImageData:image];

        }
        if(![elementName compare:@"largeimage"])
        {
            NSURL *imageURL = [NSURL URLWithString:currentElementValue];
            NSData *data =  [NSData dataWithContentsOfURL:imageURL];
            UIImage *image = [[UIImage alloc] initWithData:data];
            [aNewsInfo setLargeImageData:image];
            [image release];
        }
        [aNewsInfo setValue:currentElementValue forKey:elementName];
        [currentElementValue release];
        currentElementValue = nil;
    }
}

【问题讨论】:

    标签: iphone objective-c xcode4


    【解决方案1】:

    首先你需要做一些研究:

    转到以下链接:

    http://www.cocoadev.com/index.pl?MemoryManagement

    http://mattpatenaude.com/ch3-memory-management.html

    http://developer.apple.com/library/mac/#documentation/cocoa/conceptual/memorymgmt/Articles/MemoryMgmt.html

    然后这样做,

    currentElementValue = [[[NSMutableString alloc] initWithString:string] autorelease]

    并从

    中删除 [currentElementValue release]

    - (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName { (否则会因为释放过多导致崩溃)

    【讨论】:

    • 正确!!!由于 initWithString 本身就是一个自动释放方法,所以你不应该手动释放它.....或者你可以试试这个 :: currentElementValue = [[[NSMutableString alloc] init]; currentElementValue = [字符串复制];
    • 你也可以回答下面的*.com/questions/8860576/…。提前致谢