How can I free this NSXMLParser without crashing my application?
Below is @interface for MREntitiesConverter object which I am using to strip all html tags from string using NSXMLParser.
@interface MREntitiesConverter : NSObject {
NSMutableString* resultString;
NSString* xmlStr;
NSData *data;
NSXMLParser* xmlParser;
}
@property (nonatomic, retain) NSMutableString* resultString;
- (NSString*)convertEntitiesInString:(NSString*)s;
@end
And this is the implementation:
@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
If I free xmlParser
in the dealloc method, I crash my application, but without freeing, I am clearly losing memory.
I am new to Tools and am trying to optimize this application. Any help you can offer on this specific issue will probably help me solve other memory issues in my application.
Your disappointment :) Oisin
a source to share
Both classes and NSXMLParser free the data, causing your current crash. The only member must be resultString. You must initialize the resultString to convertEntitiesInString: not init, so the same instance can be used multiple times. You should return either self.resultString or [[save resultString] autorelease] from convert because what you are doing now will result in a double release later if you free the resultString in dealloc as you would expect. You should use resultString directly in parser: foundCharacters: instead of self.resultString which is a method call.
a source to share
Based on some really helpful suggestions, this is the latest version of my code that doesn't seem to waste memory:
@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
The only oddity is that if I trace retainCount
from resultString
just before returning, I get the counter 2
where I expected it to be 1
. Any idea why?
a source to share