如何在不崩溃我的应用程序的情况下发布此NSXMLParser?

时间:2010-04-21 03:21:33

标签: iphone objective-c cocoa memory-leaks nsxmlparser

下面是一个MREntitiesConverter对象的@interface,用于使用NSXMLParser从字符串中删除所有html标记。

@interface MREntitiesConverter : NSObject {
    NSMutableString* resultString;
    NSString* xmlStr;
    NSData *data;
    NSXMLParser* xmlParser;
}
@property (nonatomic, retain) NSMutableString* resultString;
- (NSString*)convertEntitiesInString:(NSString*)s;
@end

这是实施:

@implementation MREntitiesConverter
@synthesize resultString;
- (id)init
{
    if([super init]) {
        self.resultString = [NSMutableString string];
    }
    return self;
}

- (NSString*)convertEntitiesInString:(NSString*)s {
    xmlStr = [NSString stringWithFormat:@"<data>%@</data>", s];
    data = [xmlStr dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES];
    xmlParser = [[NSXMLParser alloc] initWithData:data];

    [xmlParser setDelegate:self];
    [xmlParser parse];

    return [resultString autorelease];
}

- (void)dealloc {
    [data release];
    //I want to release xmlParser here but it crashes the app
    [super dealloc];
}

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)s {
    [self.resultString appendString:s];
}
@end

如果我在dealloc方法中释放xmlParser我崩溃了我的应用程序但没有发布我很明显泄漏了内存。

我是乐器的新手,并试图抓住优化这个应用程序。您可以针对此特定问题提供的任何帮助都可以帮助我解决我的应用中的其他内存问题。

你的沮丧期待:)Oisin

6 个答案:

答案 0 :(得分:3)

您的类和NSXMLParser都在释放数据,这会导致您当前崩溃。唯一的成员应该是resultString。您应该在convertEntitiesInString中初始化resultString:不是init,因此可以多次使用同一个实例。你应该从convert返回self.resultString或[[resultString retain] autorelease],因为如果你在dealloc中释放resultString,你当前所做的将会导致双重释放。你应该直接在parser:foundCharacters中使用resultString:而不是self.resultString这是一个方法调用。

答案 1 :(得分:2)

我没有看到xmlParserconvertEntitiesInString:之外使用。您可以将xmlParser置于该方法的本地(不是实例变量),并在该方法中使用return [resultString autorelease]行之前将其释放。

答案 2 :(得分:2)

您确定[xmlParser发布]是否在dealloc中崩溃了应用程序? 我看到你在dealloc中有[data release],我看不到你使用alloc为它分配内存的语句。

答案 3 :(得分:0)

虽然其他两条评论是正确的(你忘记release方法中的解析器alloc,这是一个内存泄漏),我敢打赌它特意崩溃因为你设置了MREntitiesConverter类作为解析器的delegate

答案 4 :(得分:0)

我相信它是resultString,导致崩溃。这是NSMutableString,你没有为此分配任何内存。在返回[resultString autorelease]之前,还要在convertEntitiesInString中释放xmlParser;

答案 5 :(得分:0)

基于一些非常有用的消息,这是我的代码的最新版本,它似乎没有泄漏内存:

@interface MREntitiesConverter : NSObject {
    NSMutableString* resultString;
}
@property (nonatomic, retain) NSMutableString* resultString;
- (NSString*)convertEntitiesInString:(NSString*)s;
@end


@implementation MREntitiesConverter
@synthesize resultString;

- (NSString*)convertEntitiesInString:(NSString*)s {
    self.resultString = [NSMutableString string];

    NSString* xmlStr = [NSString stringWithFormat:@"<d>%@</d>", s];
    NSData *data = [xmlStr dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES];
    NSXMLParser* xmlParse = [[NSXMLParser alloc] initWithData:data];

    [xmlParse setDelegate:self];
    [xmlParse parse];
    [xmlParse release];

    return [self.resultString autorelease];
}

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)s {
    [resultString appendString:s];
}
@end

唯一的奇怪之处在于,如果我在返回之前跟踪retainCount resultString,我会得到2的计数,我原本期望它1 }。知道为什么吗?