【问题标题】:Memory Leak when using TBXML textFromElement使用 TBXML textFromElement 时的内存泄漏
【发布时间】:2011-05-10 17:17:05
【问题描述】:

我使用 TBXML 解析 XML 文件的方法收到内存泄漏。

它给了我 NSCFString 'Leaked Objects' 。当我查看堆栈跟踪时,它的最后一次调用是使用 TBXML 方法 textForElement;用于获取元素中的字符串。

如果我单击跟踪,它会将我带到 TBXML 类文件中的此方法:

+ (NSString*) textForElement:(TBXMLElement*)aXMLElement {
    if (nil == aXMLElement->text) 
        return @"";
    return [NSString stringWithCString:&aXMLElement->text[0] encoding:NSUTF8StringEncoding];

这是使用 textForElement 的方法之一:

- (NSMutableArray *)parseNewsXML
{

NSString *newsURL = @"http://www.millersville.edu/news/rss.php";

NSMutableArray *newsArray = [[NSMutableArray alloc] init];

EventArticleObject *currentArticle = [[EventArticleObject alloc] init];


tbxml = [TBXML tbxmlWithURL:[NSURL URLWithString:newsURL]];
rootXMLElement = tbxml.rootXMLElement;

if(rootXMLElement)
{
    node_channel = [TBXML childElementNamed:@"channel" parentElement:rootXMLElement];

    if(node_channel)
    {
        node_item = [TBXML childElementNamed:@"item" parentElement:node_channel];

        while(node_item)
        {
            node_traverse = [TBXML childElementNamed:@"title" parentElement:node_item];
            NSString *title = [TBXML textForElement:node_traverse];
            title = [title stringByReplacingOccurrencesOfString:@""" withString:@"\""];


            [currentArticle setTitle:title];
            node_traverse = [TBXML childElementNamed:@"link" parentElement:node_item];
            NSString *link = [TBXML textForElement:node_traverse];
            [currentArticle setLink:link];
            [currentArticle setDate:nil];

            [newsArray addObject:currentArticle];
            node_item = node_item -> nextSibling;
        }
    }
}
[currentArticle release];
return newsArray;
}

这是第二种方法也收到相同的泄漏:

- (void)parseMuAlertXML
{

time_t unixTime = (time_t) [[NSDate date] timeIntervalSince1970];

NSURL *url = [NSURL URLWithString:@"http://www.millersville.edu/alert/alert.xml"];

tbxml = [TBXML tbxmlWithURL:url];
rootXMLElement = tbxml.rootXMLElement;

if(rootXMLElement)
{
    node_alert = [TBXML childElementNamed:@"alert" parentElement:rootXMLElement];

    if(node_alert)
    {
        node_traverse = [TBXML childElementNamed:@"startdate" parentElement:node_alert];
        NSInteger startString =  [[TBXML textForElement:node_traverse] intValue];
        time_t startTime = startString;

        node_traverse = [TBXML childElementNamed:@"enddate" parentElement:node_alert];
        NSInteger endString =  [[TBXML textForElement:node_traverse] intValue];
        time_t endTime = endString;

        node_traverse = [TBXML childElementNamed:@"type" parentElement:node_alert];
        alertType = [[TBXML textForElement:node_traverse] retain];

        node_message = [TBXML childElementNamed:@"message" parentElement:node_alert];

        if(node_message)
        {
            node_traverse = [TBXML childElementNamed:@"p" parentElement:node_message];
            alertMessage = [TBXML textForElement:node_traverse];
            alertMessage = [[alertMessage stringByReplacingOccurrencesOfString:@" " withString:@" "] retain];
        }

        if((unixTime >= startTime) && (unixTime <= endTime))
        {
            [alertButton setHidden:NO];
            [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.01]];
        } else {
            [alertButton setHidden:YES];
            [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.01]];
        }
    }
}
}

有人看到那里出了什么问题吗? 谢谢。

【问题讨论】:

    标签: iphone xml ios memory-management memory-leaks


    【解决方案1】:

    您分配了 newsArray 并在函数中返回它。你是稍后发布它,你在哪里使用它?

    该工具似乎不理解这一点。它认为您已分配并且没有释放它。

    理想情况下,您应该自动释放需要从函数返回的对象。

    【讨论】:

    • 我添加了另一种方法,我收到相同的泄漏,但我没有返回任何东西。起初,另一种方法也没有返回任何东西,但仍然在泄漏。
    • 我指的是 parseNewsXML 函数。在那里,您将返回已分配的 newsArray。不知道您何时何地发布它。尝试让它自动释放并再次检查泄漏。 TBXML 类文件中的泄漏表明其 API 中存在泄漏。
    • 我正在处理 newsArray 并且没有泄漏;一定是图书馆的事。不过这很奇怪,因为我正在解析一些其他文档,这些文档在使用 textForElement 时没有给我带来任何问题..
    • 我不认为它是解析器,我发现了发生了什么。我再次查看 Stack Trace 中的泄漏点,并且“标题”和“链接”正在泄漏。它们被创建,然后被赋予 textForElement 值,然后被设置为 tempArticle 的标题和链接,它保留了这些字符串。我只是不确定如何处理这个,有什么建议吗?谢谢。
    【解决方案2】:

    您的 currentArticle 设置器可能就是它。

    您应该使用@synthesizer 使这更容易一些,否则请确保复制字符串,释放旧的,并让当前文章处理内存。如果你这样做:

    @implementation CurrentArticle
    
    - (void) setLink:(NSString*)value;
    {
         link = value; //You will either get a pointer to a value that belongs in another class, like pointing to an array instead of copying it, and changing the value, you'll be like "Why did it change?"
    
    ///////////// OR THIS:
          if(link) {
        [link release];
        } 
        link = [value copy];
        [value release];
    }
    

    合成器处理这个,可能更优雅。

    但是,是的,我看不出你的问题在上面的代码中,它似乎是整个过程中自动释放的值。

    是的,我知道这是旧的,但那是我会看的地方,我相信其他人会在这些字符串指针上寻找提醒。我们被太多的常量和快捷方式宠坏了,但是@"String" 是一个常量,如果没有保留它就会被释放。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-07-06
      • 2013-10-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多