升级到 Swift 6 后,我的照片应用出现了问题。在下面的示例中,我遇到了此错误(无法从 Sendable 闭包中引用主参与者隔离属性“photoImage”)。有人知道如何解决这个问题吗?在启动时在 .task 中将其分配给其他值也不起作用。
import SwiftUI
import PhotosUI
@Observable
final class CameraModel {
var thumbnail: String?
}
struct ContentView: View {
@State var camera = CameraModel()
@State var selectedItems: [PhotosPickerItem] = []
var body: some View {
PhotosPicker(selection: $selectedItems, photoLibrary: .shared()) {
// I’m getting an error here
photoImage
}
}
@ViewBuilder
private var photoImage: some View {
if let thumbnail = camera.thumbnail {
Image(thumbnail)
.resizable()
.aspectRatio(contentMode: .fill)
.animation(.easeInOut(duration: 0.3), value: thumbnail)
} else {
Image(systemName: "photo.on.rectangle")
}
}
}
#Preview {
ContentView(camera: CameraModel())
}
2
最佳答案
2
一种可能的解决方法是停用 actor-isolated 属性并创建一个单独的View
。我们也可以使用捕获列表thumbnail
从 actor-isolated 中获取camera
:
struct ContentView: View {
@State var camera = CameraModel()
@State var selectedItems: [PhotosPickerItem] = []
var body: some View {
PhotosPicker(selection: $selectedItems, photoLibrary: .shared()) { [thumbnail = camera.thumbnail] in
PhotoImage(thumbnail: thumbnail)
}
}
}
struct PhotoImage: View {
let thumbnail: String?
var body: some View {
if let thumbnail {
Image(thumbnail)
.resizable()
.aspectRatio(contentMode: .fill)
.animation(.easeInOut(duration: 0.3), value: thumbnail)
} else {
Image(systemName: "photo.on.rectangle")
}
}
}
1
-
嘿,我其实也在想类似的事情,但忘了将其作为副本 [thumbnail = camera.thumbnail] 传递。非常感谢!
–
|
只需标记您的photoImage
即可nonisolated
,因为协议View
标记为@MainActor
所以它的所有属性都绑定到MainActor
。闭包标签的类型是 just @Sendable label: () -> Label
,它不是独立的上下文,所以您需要标记nonisolated
。但在这里你不能引用 State 和非 Sendable 属性photoImage
struct ContentView: View {
//@State var camera = CameraModel()
@State var selectedItems: [PhotosPickerItem] = []
var body: some View {
PhotosPicker(selection: $selectedItems, photoLibrary: .shared(), label: {
photoImage
})
}
@ViewBuilder
nonisolated private var photoImage: some View { //<- mark here
...
}
}
另一个修复方法是捕获缩略图属性并在闭包中构造 View:
@Observable
final class CameraModel {
var thumbnail: String?
}
struct ContentView: View {
@State var camera = CameraModel()
@State var selectedItems: [PhotosPickerItem] = []
var body: some View {
PhotosPicker(selection: $selectedItems, photoLibrary: .shared()) { [thumbnail = camera.thumbnail] in
// I’m getting an error here
if let thumbnail {
Image(thumbnail)
.resizable()
.aspectRatio(contentMode: .fill)
.animation(.easeInOut(duration: 0.3), value: thumbnail)
} else {
Image(systemName: "photo.on.rectangle")
}
}
}
}
0
|
photoImage
在PhotosPicker
闭包中内联实现,它会起作用吗?–
–
|