【问题标题】:Swift threading multiple tasks?Swift线程多个任务?
【发布时间】:2017-10-16 19:47:09
【问题描述】:

我有一个应该显示用户名的标签。现在,我已经做了相当多的 IOS 开发,但是线程对我来说仍然有点不清楚。我如何确保这段代码完成:

User(name: "", email: "", _id: "").getCurrentUser(userId: userId)

在执行此操作之前?:

self.nameLabel.text = currentUser.name

我一直在摸索DispatchQueue,但我似乎无法弄清楚... 提前谢谢!

【问题讨论】:

  • 假设 getCurrentUser 执行异步网络操作,那么您需要将闭包传递给 getCurrentUser 并更新该闭包中的标签,如果没有关于该函数是什么的更多信息,这是不可能的可以肯定地说。
  • 如果这个调用是异步的,那么通常它也会接受一个完成闭包作为参数,或者提供一些其他的方式来在它完成时得到通知。如果getCurrentUser 方法是您的应用程序的一部分(而不是第三方框架),那么正确的答案可能是确保它使用这种方法。

标签: ios swift dispatch-queue


【解决方案1】:

作为一种解决方案,您可以使用 DispatchGroups 来执行此操作。这是一个例子:

// create a dispatch group
let group = DispatchGroup()

// go "into that group" starting it
group.enter()

// setup what happens when the group is done
group.notify(queue: .main) {
    self.nameLabel.text = currentUser.name
}

// go to the async main queue and do primatry work.
DispatchQueue.main.async {
    User(name: "", email: "", _id: "").getCurrentUser(userId: userId)
    group.leave()
}

【讨论】:

  • enter 需要在notify 之前,否则notify 将立即执行。
  • 谢谢汤姆,我更正了这个例子。这就是我从记忆中得到的。
【解决方案2】:

只需在您的getCurrentUser() 方法中发送一个通知,然后在您的 UIViewController 中添加一个观察者来更新标签。

public extension Notification.Name {
    static let userLoaded = Notification.Name("NameSpace.userLoaded")
}

let notification = Notification(name: .userLoaded, object: user, userInfo: nil)
NotificationCenter.default.post(notification)

在你的 UIViewController 中:

NotificationCenter.default.addObserver(
        self,
        selector: #selector(self.showUser(_:)),
        name: .userLoaded,
        object: nil)

func showUser(_ notification: NSNotification) {
    guard let user = notification.object as? User,
        notification.name == .userLoaded else {
            return
    }
    currentUser = user
    DispatchQueue.main.async {
        self.nameLabel.text = self.currentUser.name
    }
}

【讨论】:

    【解决方案3】:

    您必须区分 同步异步 任务。 通常,同步任务是阻塞程序执行的任务。直到前一个任务完成,下一个任务才会执行。 异步任务则相反。一旦启动,执行将转到下一条指令,您通常会通过委托或块获得此任务的结果。

    因此,如果没有更多指示,我们无法知道 getCurrentUser(:) 到底做了什么......

    根据苹果:

    DispatchQueue 管理工作项的执行。每个提交到队列的工作项都在系统管理的线程池中处理。

    不一定要在后台线程上执行工作项。它只是一个允许您在队列(可能是主队列或另一个队列)上同步或异步执行工作项的结构。

    【讨论】:

    • 感谢您的评论!对不起,我没有把它放进去:getCurrentUser() 执行一个异步 http 请求。但是,该方法在另一个文件中,因此我无法访问该文件中的nameLabel
    猜你喜欢
    • 2018-10-07
    • 1970-01-01
    • 2013-12-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多