开发者

asynchronous requests with NSURLConnection: when to release

Apple guide is very specific about releasing connection object: it's done in didFailWithError and connectionDidFinishLoading.

Yet, when I do the same, I later get this in zombi-mode

*** -[NSURLConnection releaseDelegate]: message sent to deallocated instance 0x1001045b0

It seems, there's some code in AppKit which releases connection for me.

I'd be happy to assume that Apple guide is wrong, but do not want to get some terrible memory leak or introduce some subtle incompatibility with older OSX versions or something like that.

Is it safe to ignore documentation in this case?

edit

Code creating request

  URLConnectionDelegate *delegate = [[URLConnectionDelegate alloc] initWithSuccessHandler:^(NSData *response) {
      ...
  }];
  [NSURLConnection connectionWithRequest:request delegate:delegate];  

  // I do 开发者_StackOverflow社区not release delegate when testing for this issue, not sure whether I should in general

Delegate class itself

- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
  successHandler(receivedData);

  [receivedData release];
  Block_release(successHandler);

  // do we really need this????????
  [connection release];
}


Since you’ve created your connection with

[NSURLConnection connectionWithRequest:request delegate:delegate]; 

you don’t own that connection object, hence you shouldn’t release it.

That being said, I wouldn’t recommend it. If you don’t own an object, you have no guarantee that it will outlive autorelease pool drain cycles, i.e., it could be the case that your connection object is (auto)released before it’s finished loading. Instead, create a retain declared property to hold the connection:

@property (retain) NSURLConnection *connection;

assign your connection object to the declared property:

self.connection = [NSURLConnection connectionWithRequest:request
    delegate:delegate]; 

and, when the connection finishes loading or fails, release it by assigning nil to the declared property:

self.connection = nil;

As for your delegate, if it only needs to exist whilst the connection is loading, you can autorelease it since the connection retains the delegate:

URLConnectionDelegate *delegate = [[[URLConnectionDelegate alloc]
    initWithSuccessHandler:^(NSData *response) {
    // …
}] autorelease];

self.connection = [NSURLConnection connectionWithRequest:request
    delegate:delegate]; 
0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜