Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/114.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 用于较长任务的后台线程_Ios_Swiftui_Combine_Background Thread - Fatal编程技术网

Ios 用于较长任务的后台线程

Ios 用于较长任务的后台线程,ios,swiftui,combine,background-thread,Ios,Swiftui,Combine,Background Thread,我用SwiftUI框架构建了一个iOS应用程序。 我希望根据用户是否正在运行,长时间运行任务。 因此,我使用Combine框架启动和停止一些与使用后台线程运行活动相关的进程,该线程的服务质量为.background。 然而,我注意到有时启动和停止的过程会被延迟或终止。 我可以推迟这个过程,但我不同意它被杀 我想知道如何解决这个问题? 因为如果你使用谷歌地图,点击开始导航,你的位置。 这个过程不会被扼杀。 因此,必须有一种方法在后台线程上长时间启动进程。我只是不知道怎么做。 有什么想法吗

我用SwiftUI框架构建了一个iOS应用程序。 我希望根据用户是否正在运行,长时间运行任务。 因此,我使用Combine框架启动和停止一些与使用后台线程运行活动相关的进程,该线程的服务质量为.background。 然而,我注意到有时启动和停止的过程会被延迟或终止。 我可以推迟这个过程,但我不同意它被杀

我想知道如何解决这个问题? 因为如果你使用谷歌地图,点击开始导航,你的位置。 这个过程不会被扼杀。 因此,必须有一种方法在后台线程上长时间启动进程。我只是不知道怎么做。 有什么想法吗

        self.activaity.$running
        .subscribe(on: self.BackgroundQueue)
        .receive(on: self.BackgroundQueue)
        .removeDuplicates(by: {$0 == $1})
        .sink(receiveValue: { [self] value in
                if value {
                        self.start()
                }
                else{
                        self.stop()
                }
        })
        .store(in: &self.cancellables)   


func start() {
    self.persistMetaData()
    self.persist()
    self.sensorManager.startUpdates()
   }
        

谢谢

在iOS中,“后台”一词可能意味着两件不同的事情:在后台线程上运行,或者当您的应用程序不再是最前端的应用程序,但仍在获得处理时间时

这两者只是松散地联系在一起。启动在后台线程上运行的任务与设置应用程序以在用户将其切换到后台或锁定设备后保持CPU时间不同

后台线程是贯穿代码的单独执行路径,通常(但不总是)在不同的处理器上运行,并且通常与主线程同时运行。就像你在一个厨房里有两个厨师,都在做不同的菜。他们必须共用相同的设备和用品,如果厨师一号留下了一堆东西,或者偷了厨师二号准备好的配料,那么厨师二号可能会搞砸。类似地,多个线程必须小心不要同时访问同一内存,而无法同步该访问,或同时与硬件系统通信

为了理解后台的其他含义,我们需要谈谈操作系统如何管理应用程序。如果你的应用程序是最前面的应用程序,它将在前台运行。通常情况下,如果用户交换应用程序,您会收到一个通知,通知您将被挂起。您需要停止运行计时器以保存应用程序的数据。你可以要求额外的时间在后台运行,但通常最多只有3分钟左右(从这个意义上说,后台意味着你的应用程序在屏幕上和用户交互时,会一直在下载文件或记录GPS读数)

在后台运行一段时间后,您的应用程序将切换到“暂停”状态。在这种状态下,它不会得到任何处理器时间。(你的应用程序的线程没有任何处理器时间。)一旦处于暂停状态,它可以随时终止(从内存中删除并终止),无需另行通知。如果它被杀死,它的所有线程都会被杀死,它在内存中的所有状态数据都会丢失。这就是为什么当你被告知你将被暂停时,你应该保存你的应用程序状态

允许在后台无限期运行数量非常有限的应用程序类型(逐轮导航应用程序、流媒体音乐应用程序和一到两个其他应用程序)。(我认为HealthKit应用程序是另一种允许在后台连续运行的应用程序类型,尽管我从未详细看过HealthKit。)苹果限制了可以在后台运行的应用程序,因为CPU全速运行时需要更多的功率,而任何CPU时间都需要更多的功率。苹果只允许非常特定的应用程序在后台运行,并且只有在用户授权的情况下才能运行。这让苹果(和用户)能够限制功耗并节省电池寿命。在后台运行的应用程序也会降低前台应用程序的性能,尽管硬件可以限制后台应用程序以防止出现这种情况。你的例子,谷歌地图,是一个逐轮导航应用程序。它这样声明自己,在iOS允许它在后台继续运行之前,用户必须授予它这样做的权限

忽略这些类型的应用程序并返回到您的应用程序:

如果用户在应用程序挂起时切换回应用程序,它会在停止的位置重新启动,所有状态变量保持不变,并且正在运行的前台线程和任何后台线程都会重新开始获取CPU时间

当你的应用程序终止时,所有后台线程都会随之终止。当它重新启动时,您将必须启动任何要再次运行的后台线程


当用户切换到另一个应用程序时,在后台线程上启动任务不会使你的应用程序保持运行。同样,术语background的两种用法的含义完全不同。

如果不显示一些代码,就无法回答这个问题。另外,谷歌地图导航(一个后台进程)与对不同线程的联合调用被终止完全不同。你如何获得进程终止的信息?你能显示代码吗?我编辑并添加了一些代码。我不确定线程是否被终止。但从数据的角度来看,似乎是这样的。线程不仅仅在iOS上神秘地被杀死,所以还有其他一些事情在发生。由于您还没有展示出,
self.activaity.$running
是什么,所以很难说出发生了什么。此外,没有理由将所有这些都包装到
self.BackgroundQueue.async
——您已经在执行
.receive(on:self.BackgroundQueue)
。试着编辑这个问题,以显示一个最小的,可重复的例子哦,好吧,我明白你所说的与州有关的内容。好的,这正是当用户进入应用程序并且running为true并且用户进入后台时发生的事情,应用程序仍然在运行。然而,当用户进入应用程序且running为非真时,它不会触发进程,当running为真时,进程启动。现在我的问题是如何解决它?我必须以不同的方式处理问题吗?我还没有研究过治疗