首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何使用非主线程的线程,直到类静态Bool变量为真?

如何使用非主线程的线程,直到类静态Bool变量为真?
EN

Stack Overflow用户
提问于 2019-03-30 18:49:24
回答 1查看 247关注 0票数 1

Swift新手:我使用GCD通过DispatchQueue.global(qos:.background).async{ code }来执行HealthKit查询,在执行每个查询之前,我需要等待(通过while/HealthKit循环实现)直到类静态protectedDataEncrypted: Bool (我用来表示AppleHealth数据是否加密和不可访问)是假的,我想确保GCD永远不会使用主(UI)线程来检查/睡眠静态protectedDataEncrypted: Bool,因为这会冻结应用程序。

到目前为止,我使用的方法是有效的,但是我并不100%相信如果GCD出于某种原因使用主线程检查/睡眠静态Bool,那么有什么比使用睡眠更好的方法,如下面的代码所示?

在AppDelegate中:我有以下内容:

代码语言:javascript
运行
复制
static var protectedDataEncrypted = false

    override func applicationProtectedDataDidBecomeAvailable(_ application: UIApplication) {
        AppDelegate.protectedDataEncrypted = false
    }

    override func applicationProtectedDataWillBecomeUnavailable(_ application: UIApplication) {
        AppDelegate.protectedDataEncrypted = true
    }

在一个具有DispatchQueue.global(qos:.background).async{ code }调用方法的单独类中,在执行HealthKit查询之前调用了以下方法

代码语言:javascript
运行
复制
    func waitTillUnencrypted(){

        while (AppDelegate.protectedDataEncrypted){
                    DispatchQueue.global(qos: .background).sync {
                        Thread.sleep(forTimeInterval: 2)
                    }
        }
    }

注意:使用DispatchQueue.global(qos:.background).sync调用Thread.sleep似乎可以防止UI冻结,而当我只有Thread.sleep时,它有时会冻结,如果连续地快速锁定/解锁屏幕。

到目前为止,它是有效的,但我不相信它将100%的时间起作用。

在此之前,非常感谢您。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-03-30 19:14:02

首先,不需要您自己的protectedDataEncrypted。这已经可以直接作为UIApplication.shared.isProtectedDataAvailable使用了。

你想要的是一个你可以停下来的队列。因此,创建一个处理事物的队列。如果受保护的数据不可用,请挂起。

代码语言:javascript
运行
复制
let protectedQueue = DispatchQueue(label: "protected")
if !UIApplication.shared.isProtectedDataAvailable {
    protectedQueue.suspend()
}

现在,如果可能的话,使用protectedQueue.dispatchAsync放置在该队列上的任何内容都将立即运行,或者如果没有,则只是排队。

然后你就可以像你正在做的那样,打开或关闭队列。

代码语言:javascript
运行
复制
override func applicationProtectedDataDidBecomeAvailable(_ application: UIApplication) {
    protectedQueue.resume()
}

override func applicationProtectedDataWillBecomeUnavailable(_ application: UIApplication) {
    protectedQueue.suspend()
}

尽管如此,通常最好只是构建您的操作,盲目地尝试执行自己,然后处理错误,如果它们失败了,而不是检查您是否认为它会成功。在某些竞争条件下,您可以成功地启动操作,但在完成操作之前,数据保护可能会启动。你得处理那个案子。因为您必须处理这种情况,所以通常应该让处理程序来处理没有访问权限的问题。

但是,在飞行前检查可能有用的情况下,或者如果它影响到用户可见的元素,那么上面的内容可能是有用的。

使用sleep进行轮询从来都不是答案。即使你想投票(如果可能的话,你应该避免),你也不应该使用Thread.sleep。这会将整个线程绑定起来,并防止其他任何东西使用它。如果您被迫这样做,那么进行投票的方法是用dispatchAfter重新安排自己的时间。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55434663

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档