当调用completionHandler应用:performFetchWithCompletionHandler:当背景提取是异步? [英] When to call completionHandler in application:performFetchWithCompletionHandler: when Background Fetch is async?

查看:165
本文介绍了当调用completionHandler应用:performFetchWithCompletionHandler:当背景提取是异步?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有与背景的帮助下获取后台获取内容的应用程序。

I have an app that fetches content in the background with the help of Background Fetch.

所以,如果后台获取应该采取把我的应用程序:performFetchWithCompletionHandler:方法被调用。在此方法中我使用NSURLConnection的获取内容同步。

So if a Background Fetch should take place my application:performFetchWithCompletionHandler: method is called. In this method I use NSURLConnection to fetch content asynchronous.

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

In my current implementation I only start the request and then call the completionHandler with UIBackgroundFetchResultNewData. I know that this cannot be right. So my question is, how do I correctly call the completionHandler when the async request finishes in connection:didReceiveData: method.

推荐答案

您是对的 - 你应该打电话只有当你的抓取是实际完成的完成处理。否则,iOS将可能把你的应用程序后面的连接完成之前睡觉,和应用程序不应该实际上能够确定 UIBackgroundFetchResultNewData UIBackgroundFetchResultNoData UIBackgroundFetchResultFailed 直到那时反正。你怎么知道你的连接会成功吗?

You're right — you should call the completion handler only when your fetch is actually complete. Otherwise iOS will probably put your application back to sleep before the connection completes, and apps shouldn't actually be able to determine UIBackgroundFetchResultNewData versus UIBackgroundFetchResultNoData or UIBackgroundFetchResultFailed until then anyway. How do you know your connection will succeed?

您需要保持completionHandler的保持,并调用它只是一旦连接完成。最有可能你会想一个实例变量添加到您的委托,完成处理程序复制到那里,并调用它的时候,你就大功告成了。

You need to keep hold of the completionHandler and call it only once the connection has finished. Most likely you'll want to add an instance variable to your delegate, copy the completion handler into there, and call it when you're done.

旁白:连接:didReceiveData:没有信号的请求的结束。每文档:

Aside: connection:didReceiveData: doesn't signal the end of a request. Per the documentation:

发来的连接将数据加载增量。

Sent as a connection loads data incrementally.

[...]

委托应串联的每个数据对象的内容
  交付建立完整的数据为一个URL负载。

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

您可以接收任何数目的呼叫和URL连接的净结果是所有的人的积累。

You may receive any number of calls and the net result of the URL connection is the accumulation of all of them.

编辑:您可以通过创建正确类型的实例变量和复制的块,将其存储块。块具有不同寻常的语义,因为,不同于所有其他类型的Objective-C的对象,他们最初在栈上创建的。最终的效果就是,你总是复制他们。如果他们是在栈上,当您复制,然后他们最终在堆上。如果他们已经是在堆上则复制只是作为一个保留,因为块总是一成不变呢。

you store a block by creating an instance variable of the correct type and copying the block to it. Blocks have unusual semantics because, unlike every other kind of Objective-C object, they're initially created on the stack. The net effect is just that you always copy them. If they're on the stack when you copy then they end up on the heap. If they're already on the heap then the copy just acts as a retain, since blocks are always immutable anyway.

所以:

@implementation XXMDYourClass
{
    // syntax follow the C rule; read from the centre outwards
    void (^_completionHandler)(UIBackgroundFetchResult);
}

- (id)initWithCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
    self = [super init];

    if(self)
    {
        // keep the block by copying it; release later if
        // you're not using ARC
        _completionHandler = [completionHandler copy];
    }

    return self;
}

- (void)somethingThatHappensMuchLater
{
     _completionHandler(UIBackgroundFetchResultWhatever);
}

@end

这篇关于当调用completionHandler应用:performFetchWithCompletionHandler:当背景提取是异步?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆