【问题标题】:Pass data to dispatchGroup.notify in Swift在 Swift 中将数据传递给 dispatchGroup.notify
【发布时间】:2021-09-08 08:13:52
【问题描述】:

我正在从 API 下载一些 JSON,但在我们进入下一个屏幕之前,必须完成另一个先决条件(动画)。

我决定使用DispatchGroup 来执行此操作,但也需要重新加载。

我想出了一个使用完成处理程序的解决方案,它要么是dispatchGroup.leave,要么只是移动到下一个屏幕,因为我们只需要下载一次数据。

let dispatchGroup = DispatchGroup()
var userName: String?

func fetchData() {
    dispatchGroup.enter()
    dispatchGroup.enter()
    
    resolveDataRequirements(dispatchGroup.leave)
    
    dispatchGroup.notify(queue: .main) { [weak self] in
        self?.moveToNextScreen()
    }
}

func resolveDataRequirements(_ completion: @escaping(() -> Void)) {
    api.resolve { [weak self] result in
        switch result {
        case .success(let user):
            self?.userName = user
            completion()
        case .failure:
            break
        }
    }
}

func moveToNextScreen() {
    // move to next screen, but passes the user
}

// reload data, and once the data is downloaded move to next screen
func reloadData() {
    resolveDataRequirements(moveToNextScreen)
}


// the user might choose to fetch data
fetchData()
// now if the user wanted to reload
reloadData()

现在的问题是这是在视图模型中 - 所以用户字符串实际上是我希望根除的状态。

有什么方法可以将用户字符串传递给dispatchGroup.notify 或类似的?

【问题讨论】:

    标签: swift dispatchgroup


    【解决方案1】:

    您可以像这样使用 inout 属性并更改 userName 范围:

    func fetchData() {
        var userName = ""
        dispatchGroup.enter()
        dispatchGroup.enter()
        
        resolveDataRequirements(dispatchGroup.leave, &userName)
        
        dispatchGroup.notify(queue: .main) { [weak self] in
            self?.moveToNextScreen(userName)
        }
    }
    
    func resolveDataRequirements(_ completion: @escaping(() -> Void), _ userName: inout String) {
        api.resolve { [weak self] result in
            switch result {
            case .success(let user):
                userName = user
                completion()
            case .failure:
                break
            }
        }
    }
    
    func moveToNextScreen(_ userName: String) {
        print(userName)
    }
    

    我只是不明白你为什么要调用两次 enter() 而只调用一次 leave()

    【讨论】:

    • 不需要inout,对吧?只需completion: ((String?) -> Void),然后resolveDataRequirements { dispatchGroup.leave(); userName = $0 } 就足够了,不是吗?我猜用户在“动画”上调用leave(),但确实很奇怪。
    • 我知道他在写这篇文章时不想将“userName”设置为全局变量“现在问题是这是在视图模型中 - 所以用户字符串实际上是一个状态我希望根除的东西。”当您使用 userName = $0 时,我假设“userName”是全局的,对吗?
    • 不,它仍然是 fetchData() 本地的,并且仅在该范围内有效。
    • 啊好吧!也可以。
    猜你喜欢
    • 2018-11-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-02
    • 1970-01-01
    • 2017-09-01
    • 1970-01-01
    相关资源
    最近更新 更多