iOS 开发并发问题?

2023-03-22 17:32:43 +08:00
 0littleboy

在编写用户列表模块中,后端需要并发的访问 users ,因此学了一段时间的并发,遇到了很多问题,解决了大部分,但仍然感觉代码似乎有不少问题,但由于水平不够,希望大家帮忙看看,感谢

actor UsersModel {
    private(set) var users: [User]
    private(set) var userIDs: Set<User.UserIDType>
    
    init() async {
//        users = Bundle.main.decode(file: "allUsers.json")
        userIDs = Set(["little-boy52", "0x3f", "mindexercise", "smilyt_", "zhui-ming-zhen-bai-1", "333"])
        // 升序排列
        users = (await loadAllUsers(userIDs: userIDs)).sorted { $0.contestResults?.rating ?? 0.0 > $1.contestResults?.rating ?? 0.0 }
    }
    
    func addUser(user: User) {
        
    }
    
    func addUserByID(id: User.UserIDType) async -> Bool {
        if let user = await loadUser(userid: id) {
            users.append(user)
            userIDs.insert(id)
            return true
        }
        return false
    }
    
    func deleteUser(user: User) {
        userIDs.remove(user.id)
        users.removeAll {
            return $0.id == user.id
        }
    }
    
    func contains(id: String) -> Bool {
        userIDs.contains(id)
    }
    
}

@MainActor
class UsersViewModel: ObservableObject {
    @Published var model: UsersModel? = nil
    
    func loadModel() async {
        let model = await UsersModel()
        DispatchQueue.main.async {
            // Update the UI on the main thread
            self.model = model
        }
    }
    
    var users: [User] {
        get async {
            if let model = model {
                return await model.users
            } else {
                return []
            }
        }
    }
    
    func addUser(user: User) async {
        await model?.addUser(user: user)
    }
    
    func addUserByID(id: User.UserIDType) async -> Bool {
        if model == nil {
            return false
        }
        return await model!.addUserByID(id: id)
    }
    
    func deleteUser(user: User) async {
        await model?.deleteUser(user: user)
    }
    
    func contains(id: String) async -> Bool {
        if model == nil {
            return false
        }
        return await model!.contains(id: id)
    }
}

最后调用 loadModel

// UsersView.swift

VStack {...}
.task {
    await usersVM.loadModel()
}

我在 UsersViewModel 中定义了计算字段 users,在 SwiftUI 中调用的话需要使用 ForEach(Task {await usersVM.users}.value) { user in ... },但这样的话又会报错'async' property access in a function that does not support concurrency,如何解决?

857 次点击
所在节点    iOS
2 条回复
MakHoCheung
2023-03-22 18:32:54 +08:00
好绕啊,简洁点就是
```
@State var users = []
VStack {...}
.task {
user = await usersVM.loadUsers()
}
```
MakHoCheung
2023-03-22 18:47:23 +08:00
class UsersViewModel: ObservableObject {
@Published var users = []

@MainActor
func addUsers(users : [User]) {
self.users = users
}
}

这种可以的,你并发拿 user 最后在 adduser 方法汇聚并切到主 actor

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/926269

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX