在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中,后台线程中的重复方法是不是正确?的主要内容,如果未能解决你的问题,请参考以下文章

每 N 秒在后台线程中重复一个函数

在Objective-C中调用“超级初始化” [重复]

搞懂Objective-C中的autorelease

Tomcat servlet 应用程序的后台线程 [重复]

从后台线程访问 [UIApplication sharedApplication] 可以吗?

如何在后台线程中按顺序运行任务[重复]