在objective-c中,后台线程中的重复方法是不是正确?
Posted
技术标签:
【中文标题】在objective-c中,后台线程中的重复方法是不是正确?【英文标题】:Is recurring method in background thread correct way in objective-c?在objective-c中,后台线程中的重复方法是否正确? 【发布时间】:2020-04-08 03:10:10 【问题描述】:我正在尝试以下代码,在后台线程中从服务器加载文件。如果加载失败然后再次调用相同的方法,这是在后台线程中再次调用它的正确方法吗?
[self performSelectorInBackground:@selector(loadFileFromServer:) withObject:nil];
int retryCount = 0;
- (void)loadFileFromServer
FetchServerFile *fetchF = [FetchServerFile new];
[fetchF fetchFile:^(BOOL OK)
if(OK)
[self toStart];
else
retryCount++;
if(retryCount<3)
[self performSelectorInBackground:@selector(loadFileFromServer:) withObject:nil];
else
[self exitLogic];
];
【问题讨论】:
如果第一次失败,为什么一毫秒后会成功? @matt 感谢您的建议,将在此处添加延迟功能。逻辑是失败后会再试两次,所以延迟再后台重试可以吗? 使用GDC
,忘记performInBackground
【参考方案1】:
关于performselectorinbackground:withObject:
的使用,the documentation告诉我们:
此方法在您的应用程序中创建一个新线程,将您的应用程序置于多线程模式(如果它还没有的话)。
aSelector
表示的方法必须像设置程序中的任何其他新线程一样设置线程环境。有关如何配置和运行线程的更多信息,请参阅Threading Programming Guide。
如果你想在后台线程上运行一些代码,只使用Grand Central Dispatch 会更容易(也更有效)。
话虽如此,但问题在于你为什么要将它推送到后台线程。网络代码通常异步运行,在这种情况下,在后台线程上运行这段代码没有什么意义。这只会使情况复杂化。
关于重试逻辑的细节,这取决于目的。一些应用程序使用“可达性”库之一来主动警告用户,如果他们没有连接到网络,但在这种情况下,你不会使用重试逻辑,而是你只需要一个处理程序网络重新建立后调用。
似乎重试逻辑必须在请求结束时(您正在检查请求是否成功)合并,而不是在您发起请求的开始。
另外,如果您只是尝试执行一些简单的上传和下载,您可能需要考虑使用后台 URLSessionConfiguration
,因为它可以处理各种各样的问题(例如连接问题、用户在上传前离开应用程序/下载完成等)。
【讨论】:
可以从 dipatch_get_main_queue 异步块调用第二个 performselectorinbackground:withObject: 方法吗? 我不会再使用performSelectorInBackground
了。调度到全局队列dispatch_get_global_queue
,或者如果你真的想在后台线程上运行某些东西,如果必须的话,调度到你自己的自定义后台队列。但是假设您使用的是异步网络 API(如 NSURLSession
、AFNetworking 等),您为什么要在后台线程上运行呢?以上是关于在objective-c中,后台线程中的重复方法是不是正确?的主要内容,如果未能解决你的问题,请参考以下文章