关于NSURLConnection的Apple SDK文档中的错误或混淆?

我最近一直在学习Apple SDK(适用于iPhone等),并且遇到了一些我无法理解的东西。 在http://developer.apple.com/documentation/Cocoa/Conceptual/URLLoadingSystem/Tasks/UsingNSURLConnection.html中的“使用NSURLConnection”文档中

我发现了一段奇怪的解释和示例代码。 首先它说:

下载在收到initWithRequest:delegate:消息后立即开始。 它可以在代理接收到connectionDidFinishLoading:或connection:didFailWithError:消息之前的任何时间通过发送连接取消消息来取消。

接下来,它显示了以下代码片段:

  NSURLConnection *theConnection=[[NSURLConnection alloc] initWithRequest:theRequest delegate:self];

  if (theConnection) {

    // Create the NSMutableData that will hold

    // the received data

    // receivedData is declared as a method instance elsewhere

    receivedData=[[NSMutableData data] retain];

  } else {

    // inform the user that the download could not be made

  }

所以,在我看来,下载必须在连接初始化后立即在不同的线程中启动。 这很明显,因为代码是非阻塞的,并将消息发送给委托,在这种情况下,自我。 然而,receivedData的(autorelease样式)分配发生在另一个线程启动之后。 这不是一个不安全的竞争条件吗? 如果服务器响应速度非常快(例如,在回环设备上),或者在不幸的线程调度的情况下,这会不会导致崩溃,内存泄漏或数据丢失? 在Connection初始化之前分配receivedData并不是更合理,然后在上面的else情况下释放它吗?

我对这段代码感到困惑,希望有人能为我阐明一些。 感谢您的任何信息,

Rudi Cilibrasi


没有竞赛条件。 下载在单独的线程的后台启动,但发送给代理的消息通常会在启动下载的线程上调用,以通知您下载进度。

你可以在创建连接之前分配NSData,如果这更清楚的话。 你甚至可以在连接中分配它:didReceiveData:方法,如果你想确保NSData没有被分配,除非有数据被存储。

我认为这个例子的编写方式是尽可能缩短,以免将演示文稿与大量不相关的代码混淆。

从NSURLConnection的文档:

NSURLConnection的委托方法允许对象接收关于URL请求异步加载的信息回调。 其他委托方法提供的功能允许委托定制执行异步URL加载的过程。

请注意,这些委托方法将在启动相关NSURLConnection对象的异步加载操作的线程上调用。


这里没有竞赛条件。 NSURLConnection使用NSRunLoop来分派其事件。 因此,在下一个事件循环开始之前,没有数据可以传达给您。

这意味着不会有connection:didReceiveData:调用connection:didReceiveData:直到下一个事件循环发生,无论数据何时实际返回,并且该connection:didReceiveData:将在启动加载的线程上调用。 所以你有这个运行循环的其余部分来按顺序获取所有东西。 “立即”意味着在这里“你不需要做任何事情来启动它。”

这不是一个猜想或一个可变的实现细节。 它基于Cocoa的设计原则。 为了最好地理解可可,假设几乎所有事情都发生在主线上。 虽然框架偶尔会产生线程作为实现细节,但它们总是会提供他们不知道的错觉。 因此,异步操作本质上总会出现在后面的事件循环中。 合作,而不是预先,多任务是可可的方式。

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

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

下一篇: NSURLConnection is run many times