当控制器被释放时清除挂起的NSURLConnections

我有一个控制器使用一个自定义的类,它作为NSURLConnection的委托,使HTTP GET请求。 一旦NSURLConnection失败或完成,自定义类调用控制器上的方法并传递接收数据的NSData对象。

我遇到了一个问题,即控制器正在动态创建并被推送到导航控制器的堆栈中。 该控制器在其viewDidLoad方法中生成HTTP GET请求。 如果用户快速按下导航栏上的“后退”,则该控制器将被解除分配。 如果在HTTP GET请求完成之前发生这种情况,则生成的NSURLConnection回调将成为对释放分配对象的方法调用,这会导致EXC_BAD_ACCESS。

清理任何已被实际上可能已被释放的控制器启动的未完成NSURLConnections的最佳方法是什么?

我引入了一些NSLog语句,看起来我用作NSURLConnection委托的自定义类实际上并没有收到dealloc消息。 我确保将控制器的这个类的实例设置为viewDidUnload nil,并且还可以调用release,但它似乎仍然比控制器寿命更长。


如果我理解正确,只需在viewDidUnload或dealloc方法中执行[whateverConnection cancel]。 这取消了连接。 如果您有一个自定义下载器对象,例如对于使用NSURLConnection的大图像,它几乎是相同的。 为你的类制作一个取消方法(取消连接并释放它)并在你的控制器的dealloc方法中调用它。 您还应该使用类似wasCanceled的bool标志,并且如果您的cancel方法设置了wasCanceled,则不会从您的自定义对象的委托中调用任何方法。 (你只有一个指向你的委托的弱指针,所以当其他对象调用你的cancel方法时它可能已经被释放了)。 我假设你的自定义对象的委托是视图控制器。 我有几个这样的下载者,它工作正常,即使我很快取消了下载也没有泄漏。

@interface CompaniesDownloader : NSObject /*<NSXMLParserDelegate>*/
{
    id<CompaniesDownloaderDelegate> delegate; //a view controller is the delegate
    NSMutableArray *companies;

    BOOL isWorking;    
    BOOL wasCanceled;   

    @private

    //url connection object
    NSURLConnection *companiesConnection;

    //this is where i put the binary data that gets transformed into xml
    NSMutableData *webData;

    //temporary string used when parsing xml
    NSMutableString *tmpString;

    //temporary company used when parsing xml
    Company *tmpCompany;
}

在执行中:

-(void) cancel
{
  [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible: FALSE];

  wasCanceled = TRUE;
  [companiesConnection cancel];
  [webData release];
  webData = nil;
  self.companiesConnection = nil; //OR [companiesConnection release]; companiesConnection=nil;
  isWorking = FALSE;
}

当您发出请求并在获取请求完成时释放时,您需要保留您的视图控制器

YourViewController.m
- (void)callGetRequest {
   [self retain];
}

- (void)didFinishAllGetTask {
   [self release];
}

如果用户快速按下导航栏上的“后退”,则该控制器将被解除分配。 如果在HTTP GET请求完成之前发生这种情况,则生成的NSURLConnection回调将成为对释放分配对象的方法调用,这会导致EXC_BAD_ACCESS。

当用户点击后退按钮时,取消注册视图控制器类作为该对象的委托。 (保持对视图控制器类中的对象的引用,所以你可以做一些事情,比如someObject.delegate = nil; )。 你可以在视图控制器的dealloc方法中做到这一点。

链接地址: http://www.djcxy.com/p/30583.html

上一篇: Cleaning up hanging NSURLConnections when a controller is dealloc'ed

下一篇: Mistake or confusion in Apple SDK documentation on NSURLConnection?