4

我正在努力解决异步性问题;调度,多线程,运行循环等。

有什么区别:

1) 在给定的方法中创建一个 NSURLRequest 和 NSURLConnection,并让它执行并且我们响应委托方法(didReceiveResponse、didReceiveData、connectionDidFinishLoading 等),以及

2)创建一个块并让它 dispatch_async ?

使用第一种方法,我可以访问委托方法似乎很棒(我仍然可以访问那些使用 dispatch 的方法吗?),并且委托方法的执行在触发(或接近它?)时执行

使用块/调度方法,我猜块是在它的线程中同步处理的?然后回到主线程处理结果?我一直在看的示例代码:

    dispatch_async(kBgQueue, ^{
    NSData* data = [NSData dataWithContentsOfURL: 
      kLatestKivaLoansURL];
    [self performSelectorOnMainThread:@selector(fetchedData:) 
      withObject:data waitUntilDone:YES];
});

那么,“self performSelector ....”是在收到数据后执行的吗?(我之前的意思是同步 - 也许是错误的术语)。块的下一行将我们送回主线程。

目的是什么,或者为什么会有“waitUntilDone:YES”?是不是因为如果它不存在,其他事情可能不会发生在主线程中?

上面的第一种方法还是只在主线程上执行吗?

最后,在对网页进行 JSON 查询的情况下,每种方法的优缺点是什么?一种方法比另一种方法有什么好处吗?

4

1 回答 1

2

1) 当你使用 NSURLConnection 时,无论是在你的主线程中还是在 NSOperation 中,你都可以完全控制在任何时候停止它,并跟踪它的进度。当各种事情发生时,您得到的是委托方法,但您不是坐等某事完成。如果你想在任何时候停止它,你发送它取消,然后你可以释放(或 nil)它并忘记它。

2)所以看看这个。如果您在主线程中执行此调用,它将一直等到它成功或失败。一旦开始,它必须运行成功或失败。如果在主线程中,这将阻塞您的 UI。将它放在一个块中并在其他线程上运行它,同样的事情也会发生 - 所选线程将阻塞,直到方法结束。使用'self'发送结果将保留self。因此,如果 self 是一个 UIViewController,那么即使你弹出它(认为它会被删除),它也会一直存在直到这个方法完成,天知道会发生什么。这种用法非常危险,可能经常工作,但当设备具有糟糕的 inet 连接(例如)时会发生灾难性的失败。

等待直到做是同步线程。如果您想知道该方法已在主线程上运行,然后才继续,请使用 YES。如果您只希望方法排队并且您已经完成(就像在这种情况下),您只需使用 NO。

该方法肯定会在主线程上 - 这个 Apple 向您承诺这种方法。

3)JSON

我认识的大多数用户都使用来自 NSOperations 或块的 NSURLConnections。可以取消操作(然后会取消连接) - 因此无论发生多少事情,您都可以处理按下“返回”按钮。如果查询失败,您可以查看 html 状态(您是否收到 400 或 500 错误?超时?等)

在 github 上有一个开源项目,几乎没有 200 行代码,它提供了一个优雅且易于使用的帮助类来运行操作(带有演示代码):/NSOperation-WebFetches-MadeEasy。我个人在商店中的 8 多个应用程序中使用此代码并取得了巨大成功 - 单个 OperationsRunner 通常同时进行数百次提取,并且该应用程序有多个类同时运行 OperationsRunners。

如果您在 NSOperation 中处理 JSON,您将在多核设备上获得真正的加速。

于 2012-11-17T18:11:50.527 回答