开发者

Memory Leak In Code [duplicate]

This question already has answers here: Closed 11 years ago.

Possible Duplicate:

Memory Leak In line of code

This code is works fine but it gives me a memory leak in one of the line of code the line is which showing leak indicated by purple color in the instrument by mentioning 100.0% the line is

NSXMLParser *xmlParser = [[NSXMLParser alloc] initWithContentsOfURL:url];

i'll show you my code this is appdelegate file didFinishLaunchingWithOptions method:-

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    NSURL *url = [[NSURL alloc] initWithString:@"http://www.xyz.com/news.php?page_id=1"];

    NSXMLParser *xmlParser = [[NSXMLParser alloc] initWithContentsOfURL:url];
    [url release];

    //Initialize the delegate.
    NewsParser *parser = [[NewsParser alloc] initXMLParser];

    //Set delegate
    [xmlParser setDelegate:parser];

    //Start parsing the XML file.
    BOOL success = [xmlParser parse];

    if(success)
        NSLog(@"No Errors");
    else
        NSLog(@"Error Error Error!!!");

    [parser release];
    [xmlParser release];


    // Override point for customization after application launch.
    // Add the navigation controller's view to the window and display.
    self.window.rootViewController = self.navigationController;
    [self.window makeKeyAndVisible];
    return YES;
}

and this further code is from the NewsParser file NSXMLParser Methods:-

- (NewsParser *) initXMLParser {
    [super init];
    appDelegate = (TWAppDelegate *)[[UIApplication sharedApplication] delegate];
    return self;
}

- (void)par开发者_运维百科ser:(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);
}

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

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

- (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];
            [data release];
            [aNewsInfo setLargeImageData:image];
        }
        [aNewsInfo setValue:currentElementValue forKey:elementName];
        [currentElementValue release];
        currentElementValue = nil;
    }
}

Any one plz tell me how to overcome this leak i'm about to submit my app on the app store but this is the only leak plz give your suggestions.

Thanks...


You can run the static analyzer which will usually show you the cause for the leak. It's "Analyze" in the menu, next to the "Build" command.


You know if you just use @property and @synthesize and then use the getters and setters correctly you can reduce this issue occuring about 99% of the time.

This line looks like one of the most suspect to me

appDelegate.newsArray = [[NSMutableArray alloc] init];

that is assuming that newsArray is declared as a property with retain, in which case you would be allocating an NSMutableArray which will have a retain of +1 and then setting it with a setter which (if is set as retain) will give a further +1.

This line doesn't look to great to me either

currentElementValue = [NSMutableString string];

You are assigning an autoreleased NSMutableString to an ivar without the ivar taking a retain on it. This could lead to more difficult to track issues later.

Some one pointed out that the init method is not properly written - it is not the problem but should still be fixed. It should look something more like this

- (NewsParser *)initXMLParser 
{
    self = [super init];
    if (self) {
        appDelegate = (TWAppDelegate *)[[UIApplication sharedApplication] delegate];
    }
    return self;
}


Instead of doing

NSXMLParser *xmlParser = [[NSXMLParser alloc] initWithContentsOfURL:url];

Do the following

NSData *xmlData = [NSData dataWithContentsOfURL:[NSURL URLWithString:url]]; 
NSXMLParser *xmlParser = [[NSXMLParser alloc] initWithData:xmlData];

The initWithContentsOfURL does not properly release the url, hence the memory leak. Luckily initWithData does not have this issue, providing a neat way of working around this memory leak.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜