Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/27.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_Objective C_Grand Central Dispatch - Fatal编程技术网

Ios 如何在后台状态下运行非主队列?

Ios 如何在后台状态下运行非主队列?,ios,objective-c,grand-central-dispatch,Ios,Objective C,Grand Central Dispatch,请看一下这段非常简单的代码: dispatch_async(dispatch_get_main_queue(), ^{ for (int i = 0; i < 100; i++) { NSLog(@"LOOP %d", i); sleep(1); } }); dispatch\u async(dispatch\u get\u main\u queue()^{ 对于(int i=0;i

请看一下这段非常简单的代码:

dispatch_async(dispatch_get_main_queue(), ^{
   
    for (int i = 0; i < 100; i++)
    {
        NSLog(@"LOOP %d", i);
        sleep(1);
    }
});
dispatch\u async(dispatch\u get\u main\u queue()^{
对于(int i=0;i<100;i++)
{
NSLog(@“循环%d”,i);
睡眠(1);
}
});
如果我将应用程序发送到后台状态,它仍在运行。但是,如果我将执行放在非主队列上,如下所示:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
    
    for (int i = 0; i < 100; i++)
    {
        NSLog(@"LOOP %d", i);
        sleep(1);
    }
});
调度异步(调度获取全局队列(调度队列优先级高,0)^{
对于(int i=0;i<100;i++)
{
NSLog(@“循环%d”,i);
睡眠(1);
}
});
然后,当我的应用程序进入后台时,执行将暂停。在非主队列上调度时,是否可以使其在后台状态下运行

我需要指出的是,我在运行我的应用程序时启用了以下后台模式:

<key>UIBackgroundModes</key>
<array>
    <string>bluetooth-central</string>
    <string>voip</string>
</array>
ui背景模式
蓝牙中心
网络电话

请尝试使用
NSProcessInfo PerformeExpiringActivityWithReason
API

[[NSProcessInfo processInfo] performExpiringActivityWithReason:@"myReason" usingBlock:^(BOOL expired)
{
  // This block is run on a separate (background) thread
  // Put your code here...
}
请注意,这只是对正在后台处理的进程请求一些额外的CPU时间。。。您不能无限期地运行背景代码


当您即将被杀死时,将使用
expired==YES第二次调用该块。

请尝试使用
NSProcessInfo PerformeExpiringActivityWithReason
API

[[NSProcessInfo processInfo] performExpiringActivityWithReason:@"myReason" usingBlock:^(BOOL expired)
{
  // This block is run on a separate (background) thread
  // Put your code here...
}
请注意,这只是对正在后台处理的进程请求一些额外的CPU时间。。。您不能无限期地运行背景代码


当您即将被杀死时,该块将在
expired==YES
的情况下第二次调用。

除了使用
performExpiringActivityWithReason
,您还可以使用
UIBackgroundTaskIdentifier
API:

// Perform the task on a background queue.
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
   // Request the task assertion and save the ID.
   self.backgroundTaskID = [[UIApplication sharedApplication]
              beginBackgroundTaskWithName: @"Finish Pending Tasks" expirationHandler:^{
       // End the task if time expires.
       [[UIApplication sharedApplication] endBackgroundTask:self.backgroundTaskID];
       self.backgroundTaskID = UIBackgroundTaskInvalid;
   }];
        
   // Add your code here.
        
   // End the task assertion.
   [[UIApplication sharedApplication] endBackgroundTask:self.backgroundTaskID];
   self.backgroundTaskID = UIBackgroundTaskInvalid;
};
过期处理程序是在应用程序被终止之前调用的,但不要计划使用此方法执行计算代价高昂的任务,因为操作系统有系统范围的时间限制,这超出了开发人员的控制范围

如果您需要在后台执行特定任务,例如网络获取等系统事件,那么考虑使用后台模式。

在本例中,使用UIKit API的优点是,您可以在for循环中查询
[[UIApplication sharedApplication]backgroundTimeRemaining]
,以执行任何最后一分钟的清理步骤


请注意,如果您使用的是应用程序扩展,苹果公司建议您使用
NSProcess
API,因此建议将根据使用情况而有所不同。

除了使用
performExpiringActivityWithReason
,您还可以使用
UIBackgroundTaskIdentifier
API:

// Perform the task on a background queue.
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
   // Request the task assertion and save the ID.
   self.backgroundTaskID = [[UIApplication sharedApplication]
              beginBackgroundTaskWithName: @"Finish Pending Tasks" expirationHandler:^{
       // End the task if time expires.
       [[UIApplication sharedApplication] endBackgroundTask:self.backgroundTaskID];
       self.backgroundTaskID = UIBackgroundTaskInvalid;
   }];
        
   // Add your code here.
        
   // End the task assertion.
   [[UIApplication sharedApplication] endBackgroundTask:self.backgroundTaskID];
   self.backgroundTaskID = UIBackgroundTaskInvalid;
};
过期处理程序是在应用程序被终止之前调用的,但不要计划使用此方法执行计算代价高昂的任务,因为操作系统有系统范围的时间限制,这超出了开发人员的控制范围

如果您需要在后台执行特定任务,例如网络获取等系统事件,那么考虑使用后台模式。

在本例中,使用UIKit API的优点是,您可以在for循环中查询
[[UIApplication sharedApplication]backgroundTimeRemaining]
,以执行任何最后一分钟的清理步骤


请注意,如果您使用的是应用程序扩展,苹果公司建议您使用
NSProcess
API,因此建议会根据使用情况而有所不同。

任何队列(包括主队列)上的内容都不可能在后台无限期运行。第一块代码将导致你的应用程序最终被强制终止,而不是因为阻塞主线程而暂停。如果您没有看到这一点,那么您可能是在Xcode下运行的(这放松了一些规则)。iOS有很多在后台运行的工具,但没有通用工具。你使用哪种工具取决于你正在解决的问题。他们都没有解决“在后台运行我想要的任何东西。”我忘了提到我已经启用了一些后台模式。我已经更新了我的问题。如果你想在用户离开应用程序后用几秒钟(最多30秒)来完成某件事情,请看,但这只能为你赢得30秒。你不能一直在后台运行。有关更多信息,请参阅。任何队列(包括主队列)上的内容都不可能在后台无限期运行。第一块代码将导致你的应用程序最终被强制终止,而不是因为阻塞主线程而暂停。如果您没有看到这一点,那么您可能是在Xcode下运行的(这放松了一些规则)。iOS有很多在后台运行的工具,但没有通用工具。你使用哪种工具取决于你正在解决的问题。他们都没有解决“在后台运行我想要的任何东西。”我忘了提到我已经启用了一些后台模式。我已经更新了我的问题。如果你想在用户离开应用程序后用几秒钟(最多30秒)来完成某件事情,请看,但这只能为你赢得30秒。你不能一直在后台运行。有关更多信息,请参阅。我忘了提到我启用了一些后台模式。我已经更新了我的问题。请仔细查看BG模式仅允许您在代理回调上添加逻辑,有关更多信息,请参阅。类似地,voip.ok。谢谢你,伙计。这似乎很有效。我需要更新我的背景模式知识。我以为他们允许任何形式的后台执行我忘了提到我启用了一些后台模式。我已经更新了我的问题。请仔细查看BG模式仅允许您在代理回调上添加逻辑,有关更多信息,请参阅。类似地,voip.ok。谢谢你,伙计。这似乎很有效。我需要更新我的背景模式知识。我认为他们允许任何形式的后台执行