3
votes

Hello another stupid question regarding leaks and also NSURLConnection. How do i release it? Is it enough if i release in the following 2 methods?

(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
(void)connectionDidFinishLoading:(NSURLConnection *)connection

Because in instruments it shows me the line where I alloc my connection as the source of leaking.

(EDIT1: OK I don't get it. After the following code my urlConnection has a retain count of 2. WTF?)

NSURLConnection *urlConnection = [[NSURLConnection alloc] initWithRequest: urlRequest delegate: self];

This is the line that instruments points me to.

EDIT2: here is some code:

I create the connection here

- (void) makeRequest
{

    //NSString *urlEncodedAddress = [self.company.street stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding];

    NSString *urlString = [[NSString alloc] initWithFormat:
                               @"http://maps.google.com/maps/api/geocode/xml?latlng=%f,%f&sensor=false",
                               bestEffort.coordinate.latitude,bestEffort.coordinate.longitude];
    debugLog(@"%@",urlString);

    NSURL *url = [[NSURL alloc] initWithString: urlString];
    [urlString release];
    NSURLRequest *urlRequest = [[NSURLRequest alloc] initWithURL: url];
    [url release];
    NSURLConnection *urlConnection = [[NSURLConnection alloc] initWithRequest: urlRequest delegate: self];
  debugLog(@"connection created %@ rc %i", urlConnection, urlConnection.retainCount);
    [urlRequest release];
    connection = urlConnection;
}

I release it here

-(void)connection:(NSURLConnection *)_connection didFailWithError:(NSError *)error
{
    debugLog(@"ERROR with the connection: %@", error.localizedDescription);
    //[activityIndicator setHidden:YES];

  debugLog(@"connection will be released or else %@ %i", _connection, [_connection retainCount]);

    [connection release];
    connection = nil;
    [webData release];
    webData = nil;

    if (!cancel)
        [delegate rgc_failedWithError: self : error];

    isWorking = FALSE;

}

Or here

-(void)connectionDidFinishLoading:(NSURLConnection *)_connection
{
  debugLog(@"connection will be released (or else) %@ %i", _connection, [_connection retainCount]);

    [connection release];
    connection = nil;

    debugLog(@"DONE. Received Bytes: %d", [webData length]);
    //NSString *theXML = [[NSString alloc] initWithBytes: [webData mutableBytes] length:[webData length] encoding:NSUTF8StringEncoding];
    //debugLog(@"%@",theXML);
    //[theXML release];
        .....
        .....
}

EDIT3: Problem solved by not caring whether it's leaking or not! Simple!

1
If you post some source code it will be a lot easier to give you a correct answer to the questionClaus Broch
Well i make a connection, right away it has rc: 2 (!). Before releasing in the error or success event handlers it still has 2 rc.gyozo kudor
BTW if i do an extra release just after alloc it gives me an EXC_BAD_ACCESS in connectionDidFinishLoading :)gyozo kudor
Don't worry about that retain count. The underlying framework will retain the connection as needed, and release it appropriately. It crashes because when you add an extra release, it's basically released 3 times, whereas it should be 2.Rengers
Well i wouldn't worry about retain count either if instruments wouldn't report it as leaking. That was just a quick test with the extra release.gyozo kudor

1 Answers

3
votes

You're correct to release it in the delegate methods, however the analysis tools like instruments and the clang analyser aren't clever enough to deal with that and report a false positive. I'd be inclined to file a bug with apple, it will certainly be a duplicate but will tell them that more developers are finding this annoying.