ios – 何时在应用程序中调用completionHandler:performFetchWithCompletionHandler:当后台提取为异步时?

前端之家收集整理的这篇文章主要介绍了ios – 何时在应用程序中调用completionHandler:performFetchWithCompletionHandler:当后台提取为异步时?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有一个应用程序,在后台提取的帮助下在后台获取内容.

因此,如果应该进行后台提取我的应用程序:performFetchWithCompletionHandler:方法调用.在这个方法中,我使用NSURLConnection来异步获取内容.

在我当前的实现中,我只启动请求,然后使用UIBackgroundFetchResultNewData调用completionHandler.我知道这不可能是正确的.所以我的问题是,当异步请求在连接中完成时,如何正确调用completionHandler:didReceiveData:方法.

解决方法

你是对的 – 只有当你的fetch实际完成时才应该调用完成处理程序.否则,iOS可能会在连接完成之前让您的应用程序重新进入休眠状态,并且应用程序实际上无法确定UIBackgroundFetchResultNewData与UIBackgroundFetchResultNoData或UIBackgroundFetchResultFailed,直到那时为止.你怎么知道你的联系会成功?

您需要保持completionHandler并仅在连接完成后调用它.很可能你会想要为你的委托添加一个实例变量,将完成处理程序复制到那里,并在你完成后调用它.

旁白:connection:didReceiveData:不表示请求结束.根据文件

Sent as a connection loads data incrementally.

[…]

The delegate should concatenate the contents of each data object
delivered to build up the complete data for a URL load.

您可能会收到任意数量的呼叫,并且URL连接的最终结果是所有呼叫的累积.

编辑:通过创建正确类型的实例变量并将块复制到其中来存储块.块具有不寻常的语义,因为与其他类型的Objective-C对象不同,它们最初是在堆栈上创建的.净效果只是你总是复制它们.如果你在复制时它们在堆栈中,那么它们最终会堆在堆上.如果它们已经在堆上,则副本只是作为保留,因为块总是无论如何都是不可变的.

所以:

  1. @implementation XXMDYourClass
  2. {
  3. // Syntax follow the C rule; read from the centre outwards
  4. void (^_completionHandler)(UIBackgroundFetchResult);
  5. }
  6.  
  7. - (id)initWithCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
  8. {
  9. self = [super init];
  10.  
  11. if(self)
  12. {
  13. // keep the block by copying it; release later if
  14. // you're not using ARC
  15. _completionHandler = [completionHandler copy];
  16. }
  17.  
  18. return self;
  19. }
  20.  
  21. - (void)somethingThatHappensMuchLater
  22. {
  23. _completionHandler(UIBackgroundFetchResultWhatever);
  24. }
  25.  
  26. @end@H_502_30@

猜你在找的iOS相关文章