【问题标题】:Where is the leak in my NSXMLParser code?我的 NSXMLParser 代码中的泄漏在哪里?
【发布时间】:2011-10-28 04:30:53
【问题描述】:

我已经设置了一个 NSXMLParser 来解析 Twitter 提要,但是我遇到了内存泄漏,并且在使用了大约一百次工具之后,我无法弄清楚它在哪里!下面是我的 NSXMLParser 代码,它在 ASIHTTPRequest 接收到数据时解析。

-(void)ProcessAndParse{

    NSURL *url = [config urlForFeed:@"Twitter"];
    ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
    [request setDelegate:self];
    [request startAsynchronous];

}

- (void)requestFinished:(ASIHTTPRequest *)request
{
    NSData *responseData = [request responseData];
   myparser = [[NSXMLParser alloc] initWithData:responseData];
    [myparser setDelegate:self];
    [myparser setShouldResolveExternalEntities:YES];
    [myparser parse];



}

-(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
    currentElement = [elementName copy];
}

-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName{


}

-(void)parserDidEndDocument:(NSXMLParser *)parser{


}

-(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{




}

我知道这里有很多遗漏,但我试图在继续之前阻止这种泄漏。它似乎以 didStartElement 方法中的 currentElement = [elementName copy]; 为中心。

【问题讨论】:

    标签: iphone objective-c ios cocoa-touch nsxmlparser


    【解决方案1】:

    你需要先释放前一个元素,然后再为 currentElement 分配一个新元素,否则旧元素不会有任何其他引用,它会被泄露。所以你可以这样做:

    [currentElement release];
    currentElement = [elementName copy];
    

    或者,您可以将您的 ivar currentElement 属性声明为副本,然后简单地执行以下操作:

    //This releases previous value, and copies the new Value.
    
    self.currentElement = elementName;
    

    【讨论】:

    • currentElement 是一个 ivar,要允许这个我必须设置一个 @property?用什么参数?
    • 或者,为该属性使用关键字retain,然后删除副本。真的不能把所有代码都放在评论里,所以我添加一个答案。
    • @Perception,在这种情况下,最好复制属性。
    • 让我做更多的测试!完成后我一定会勾选答案:)
    • @MrPink 看到我更新的答案,我认为第二个选项更干净。
    【解决方案2】:

    根据 Oscar 回答中的 cmets,您将 currentElement 作为委托类的属性。我在您的代码中发现了两个问题:


    您正在创建一个 XML 解析器并且从未发布它。为了解决这个问题:

    myparser = [[[NSXMLParser alloc] initWithData:responseData] autorelease];
    

    您正在泄漏 currentElement 属性。为了解决这个问题:

    在你的头文件中确保你的属性是用保留关键字定义的

    @property (nonatomic, retain) NSString * currentElement;
    

    在你的实现文件中,正确使用你的属性

    self.currentElement = elementName;
    

    这应该可以解决所有问题。

    【讨论】:

      【解决方案3】:

      看起来您正在为 didStartElement 中的 currentElement 分配内存,但我没有看到您释放它的任何地方。看起来您正在为解析器分配内存,但没有在 requestFinished 中释放它

      【讨论】:

        【解决方案4】:

        代码似乎不完整。不过,为了在黑暗中试一试,我看到了两个分配但没有释放:

        myparser = [[NSXMLParser alloc] initWithData:responseData];
        

        还有……

        currentElement = [elementName copy];
        

        两个 alloc 都返回一个保留的对象,您需要释放它。

        【讨论】:

          最近更新 更多