gpt4 book ai didi

ios - 何时在应用程序 :performFetchWithCompletionHandler: when Background Fetch is async? 中调用 completionHandler

转载 作者:可可西里 更新时间:2023-11-01 03:37:48 26 4
gpt4 key购买 nike

我有一个应用程序可以借助 Background Fetch 在后台获取内容。

因此,如果发生后台提取,我的 application:performFetchWithCompletionHandler: 方法将被调用。在此方法中,我使用 NSURLConnection 来异步获取内容。

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

最佳答案

你是对的——你应该只在抓取实际完成时调用完成处理程序。否则 iOS 可能会在连接完成之前让您的应用程序重新进入休眠状态,并且应用程序实际上不应该能够确定 UIBackgroundFetchResultNewDataUIBackgroundFetchResultNoDataUIBackgroundFetchResultFailed 无论如何直到那时。你怎么知道你的连接会成功?

您需要保留 completionHandler 并仅在连接完成后调用它。您很可能希望向您的委托(delegate)添加一个实例变量,将完成处理程序复制到那里,并在完成后调用它。

旁白: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 连接的最终结果是所有调用的累积。

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

所以:

@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

关于ios - 何时在应用程序 :performFetchWithCompletionHandler: when Background Fetch is async? 中调用 completionHandler,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19414317/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com