Search code examples
iphoneobjective-cmemory-leakshttprequestnsmutabledata

memory leak with NSMutableData


I have a class for connecting with httprequests. I am getting a memory leak for "NSMutableData" altho I am releasing it in "didFailWithError" and in "connectionDidFinishLoading" of the connection object:

- (BOOL)startRequestForURL:(NSURL*)url {

[url retain];


NSMutableURLRequest* urlRequest = [[NSMutableURLRequest alloc] initWithURL:url];
// cache & policy stuff here
[[NSURLCache sharedURLCache] removeAllCachedResponses];
[urlRequest setHTTPMethod:@"POST"];
[urlRequest setHTTPShouldHandleCookies:YES];
NSURLConnection* connectionResponse = [[[NSURLConnection alloc] initWithRequest:urlRequest delegate:self] autorelease];
if (!connectionResponse)
{
    // handle error
    return NO;
} else {
    receivedData = [[NSMutableData data] retain]; // memory leak here!!!
}

[url release];

[urlRequest release];


return YES;}

- (void)connection:(NSURLConnection*)connection didFailWithError:(NSError*)error {
UIAlertView *alert =
[[[UIAlertView alloc]
  initWithTitle:NSLocalizedString(@"Connection problem", nil)
  message:NSLocalizedString(@"A connection problem detected. Please check your internet connection and try again.",nil)

  delegate:self
  cancelButtonTitle:NSLocalizedString(@"OK", nil)
  otherButtonTitles:nil, nil]
 autorelease];
[alert show];

[connectionDelegate performSelector:failedAction withObject:error];
[receivedData release];}

- (void)connectionDidFinishLoading:(NSURLConnection*)connection {
[connectionDelegate performSelector:succeededAction withObject:receivedData];
[receivedData release];}

Solution

  • The static analyser will call this a leak because you are not guaranteeing that either of the methods featuring a release will actually be called.

    If you set receivedData as a retained property, and do

    self.receivedData = [NSMutableData data];
    

    Then in your dealloc (and also your didFail and didFinish, instead of the release):

    self.receivedData = nil;
    

    You will be OK.

    As jbat100 points out, you are also leaking url and urlRequest if the !connectionResponse, unless you have omitted this code from the question