如何减少SwiftUI中大量图像的内存占用

如何减少SwiftUI中大量图像的内存占用,swift,swiftui,Swift,Swiftui,我在玩SwiftUI,目前我正在努力处理图像。基本上,我想显示一个无限滚动的图像列表,但我想保持内存使用合理 我有以下(被截断的)代码: struct HomeView:View{ @国家私有var墙纸:可加载=.notRequested @国家私有变量currentPage=1 @环境(\.container)私有变量容器 var body:一些观点{ 内容 .onAppear{loadWallpapers()} } 私有var内容:一些观点{ VStack{ 墙纸列表(数据:wallpaps

我在玩SwiftUI,目前我正在努力处理图像。基本上,我想显示一个无限滚动的图像列表,但我想保持内存使用合理

我有以下(被截断的)代码:

struct HomeView:View{
@国家私有var墙纸:可加载=.notRequested
@国家私有变量currentPage=1
@环境(\.container)私有变量容器
var body:一些观点{
内容
.onAppear{loadWallpapers()}
}
私有var内容:一些观点{
VStack{
墙纸列表(数据:wallpaps.value???[])
// ...
}
}
私有func墙纸列表(数据:[墙纸]->一些视图{
滚动视图{
LazyVStack(间距:5){
ForEach(数据){w in
networkImage(url:w.thumbs.original)
.onAppear{loadNextPage(当前:w.id)}
}
}
}
}
private func networkImage(url:String)->某些视图{
//我用https://github.com/onevcat/Kingfisher 处理图像加载的步骤
KFImage(URL(字符串:URL))
// ...
}
私有func加载墙纸(){
container.interactors.wallpaps.load(数据:$wallpaps,第页:currentPage)
}
私有函数加载下一页(当前:字符串){
// ...
}
}
struct wallpersinteractor:PWallpapersInteractor{
让状态:存储
出租经纪人:PWallpapersAgent
func加载(数据:LoadableSubject,页码:Int){
let store=CancelBag()
data.wrappedValue.setLoading(存储:存储)
Just.withErrorType((),Error.self)
.flatMap{uuin
agent.loadwallpaps(page:page)//此处进行网络呼叫
}
.map{中的响应
答复.数据
}
.sink{subCompletion in
如果案例失败(错误)=子完成{
data.wrappedValue.setFailed(错误:error)
}
}接收值:{
如果var currentWallpaps=data.wrappedValue.value{
CurrentWallpaps.append(contentsOf:$0)//\
data.wrappedValue.setLoaded(值:currentWallpapers)
}否则{
data.wrappedValue.setLoaded(值:$0)
}
}
.商店(在:商店)
}
}
因为每次请求新的一批图像时,我都会将新数据附加到我的
绑定中
,所以内存消耗很快就会变得非常高

当我到达第三页时,我尝试使用
.removeFirst(pageSize)
从数组中删除数据,这样我的数组最多包含
2*pageSize
元素(
pageSize
在本例中为64)。但这样做会让我的列表变得紧张不安,因为内容增加了,造成的问题比解决的问题还多

我试图寻找一个解决方案,但令人惊讶的是,在这个特定的主题上我没有找到任何东西,我是否遗漏了一些明显的东西

struct HomeView: View {
    @State private var wallpapers: Loadable<[Wallpaper]> = .notRequested
    @State private var currentPage = 1

    @Environment(\.container) private var container

    var body: some View {
        content
            .onAppear { loadWallpapers() }
    }

    private var content: some View {
        VStack {
            wallpapersList(data: wallpapers.value ?? [])

            // ...
        }
    }

    private func wallpapersList(data: [Wallpaper]) -> some View {
        ScrollView {
            LazyVStack(spacing: 5) {
                ForEach(data) { w in
                    networkImage(url: w.thumbs.original)
                        .onAppear { loadNextPage(current: w.id) }
                }
            }
        }
    }

    private func networkImage(url: String) -> some View {
        // I use https://github.com/onevcat/Kingfisher to handle image loading
        KFImage(URL(string: url))
            // ...
    }

    private func loadWallpapers() {
        container.interactors.wallpapers.load(data: $wallpapers, page: currentPage)
    }

    private func loadNextPage(current: String) {
        // ...
    }
}
struct WallpapersInteractor: PWallpapersInteractor {
    let state: Store<AppState>
    let agent: PWallpapersAgent

    func load(data: LoadableSubject<[Wallpaper]>, page: Int) {
        let store = CancelBag()
        data.wrappedValue.setLoading(store: store)

        Just.withErrorType((), Error.self)
            .flatMap { _ in
                agent.loadWallpapers(page: page) // network call here
            }
            .map { response in
                response.data
            }
            .sink { subCompletion in
                if case let .failure(error) = subCompletion {
                    data.wrappedValue.setFailed(error: error)
                }
            } receiveValue: {
                if var currentWallpapers = data.wrappedValue.value {
                    currentWallpapers.append(contentsOf: $0) // /!\
                    data.wrappedValue.setLoaded(value: currentWallpapers)
                } else {
                    data.wrappedValue.setLoaded(value: $0)
                }
            }
            .store(in: store)
    }
}