【问题标题】:Asynchronous NSURLConnection on separate thread fails to call delegate methods单独线程上的异步 NSURLConnection 无法调用委托方法
【发布时间】:2012-02-29 11:43:15
【问题描述】:

我在单独的线程上运行 NSURLConnection(我知道它是异步的,并且在主线程上运行时可以工作),但即使我将父线程作为委托传递,它也不会进行委托调用。有谁知道怎么做?

代码:

-(void)startConnectionWithUrlPath:(NSString*)URLpath {

//initiates the download connection - setup
NSURL *myURL = [[NSURL alloc] initWithString:URLpath];

myURLRequest = [NSMutableURLRequest requestWithURL:myURL cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:60];
[myURL release];


//initiates the download connection on a seperate thread
[NSThread detachNewThreadSelector:@selector(startDownloading:) toTarget:self withObject:self];

}


-(void)startDownloading:(id)parentThread {

 NSAutoReleasePool *pool = [[NSAutoReleasePool alloc] init];

 [NSURLConnection connectionWithRequest:myURLRequest delegate:parentThread];
 //The delegate methods are setup in the rest of the class but they are never getting called...

 [pool drain];
}

编辑*

我需要在单独的线程上运行 NSURLConnection 的原因是因为我正在我的 iPhone 应用程序中下载一些东西,并且当用户锁定屏幕时下载会取消(如果用户只是按下主页按钮并且应用程序运行它会继续正常进入后台)。我知道这是由于我在主线程上异步运行连接而不是单独运行连接。

我在启动 NSURLConnection 时也尝试过这段代码(不在单独的线程中):

  NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:myURLRequest delegate:self startImmediately:NO];
   [connection scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
   [connection start];
   [connection release];

但我也有同样的问题,即在屏幕锁定时取消下载。

*更新

要在下面添加 Thomas 的答案(请注意,James Webster 的答案对于线程的退出也是正确的)Apple 文档解释说: “暂停状态 - 应用程序在后台但未执行代码。系统自动将应用程序移动到此状态,并且在此之前不会通知它们。暂停时,应用程序保留在内存中但不执行任何代码。”

由于当用户锁定屏幕时,应用程序会进入后台状态,而不是立即进入暂停状态,所有执行都会停止并终止任何下载,并且不会发出即将发生的警告......可能会有通知告诉我用户已锁定屏幕,但我还没有找到。

因此,当应用程序进入后台时,我会暂停(保存某些信息并取消 NSURLConnection)所有下载,并在它再次激活时使用 HTTP Range 标头恢复它。 这是一种可行但不理想的解决方法,因为下载不是在后台进行的,这会对用户体验产生负面影响……真可惜。

【问题讨论】:

  • 您用于 NSURLConnection 请求的方法本身是异步的,因此即使您不分离新线程,它也将是多线程操作。
  • 编辑问题以更好地解释我的问题。

标签: iphone objective-c multithreading nsurlconnection nsurlconnectiondelegate


【解决方案1】:

由于你的 NSURLConnection 是异步的,你的 -startDownloading 方法会立即结束,线程退出。

您确实应该在主运行循环上安排您的连接(或使用 GCD)。

设备锁定是另一个问题。当设备锁定时,您的应用程序将暂停以节省电池寿命。您可以请求an extra amount of time when suspending 以完成下载。

【讨论】:

  • 谢谢。我更新了我的问题,以建立在你的答案之上。请求更多时间似乎仅适用于后台应用,而不是那些暂停的应用。
【解决方案2】:

我认为您的问题可能是 NSURLConnection 在您退出 startDownloading: 消息后立即被释放(或者更准确地说是在您的自动释放池耗尽时)

但是,我认为无论如何您的方法可能有点粗俗。 NSURLConnection 您使用它的方式是异步的,并且无论如何都会显示为线程。

试试这个,看看它是否像你期望的那样工作(即你的应用在你的连接繁忙时不会暂停)

-(void)startConnectionWithUrlPath:(NSString*)URLpath {

    //initiates the download connection - setup
    NSURL *myURL = [[NSURL alloc] initWithString:URLpath];

    myURLRequest = [NSMutableURLRequest requestWithURL:myURL cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:60];
    [myURL release];

    [NSURLConnection connectionWithRequest:myURLRequest delegate:self];
}

【讨论】:

  • 编辑问题以更好地解释我的问题。
  • 好的,您的编辑很有意义。那么请注意我回答的第一部分。看来您的 NSURLConnection 几乎立即被释放了。
  • 这个答案在我更新的问题中被引用为也是正确的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-29
相关资源
最近更新 更多