使用带有SwiftUI的图像和页面视图时内存不足

使用带有SwiftUI的图像和页面视图时内存不足,swift,memory,uikit,swiftui,uipageviewcontroller,Swift,Memory,Uikit,Swiftui,Uipageviewcontroller,我正在编写一个应用程序,向用户显示他们可以快速浏览和放大的大型图片,类似于照片应用程序或书籍。我正试图用SwiftUI写这篇文章。我一直在遵循,我已经修改了代码以读取json文件来创建一个“Imageslides”数组,这是一种保存图像和有关图像的信息的方法。然后,我使用PageView和PageViewController显示ContentView>ContentView显示图像,并使用一些按钮显示有关我正在显示的图像的文本。我的问题是,当我浏览页面时,内存会不断增加,直到应用程序崩溃。现在,

我正在编写一个应用程序,向用户显示他们可以快速浏览和放大的大型图片,类似于照片应用程序或书籍。我正试图用SwiftUI写这篇文章。我一直在遵循,我已经修改了代码以读取json文件来创建一个“Imageslides”数组,这是一种保存图像和有关图像的信息的方法。然后,我使用PageView和PageViewController显示ContentView>ContentView显示图像,并使用一些按钮显示有关我正在显示的图像的文本。我的问题是,当我浏览页面时,内存会不断增加,直到应用程序崩溃。现在,如果我使用UIKit,我可以使用

if let imgPath = Bundle.main.path(forResource: name, ofType: nil)
    {
        return UIImage(contentsOfFile: imgPath)
    }
但我看不出如何在swiftUI中使用contentsOfFile和Image,或者在不需要图像时使用另一种方法来释放内存。我将图像放在资源文件夹中,而不是资源库中。 谢谢你的帮助

//data.swift - reading from json, mainly from apple's tutorials
import Foundation
import UIKit
import SwiftUI

let imageData: [Imageslide] = load("imageData.json")

func load<T: Decodable>(_ filename: String) -> T {
    let data: Data

    guard let file = Bundle.main.url(forResource: filename, withExtension: nil)
        else {
            fatalError("Couldn't find \(filename) in main bundle.")
    }

    do {
        data = try Data(contentsOf: file)
    } catch {
        fatalError("Couldn't load \(filename) from main bundle:\n\(error)")
    }

    do {
        let decoder = JSONDecoder()
        return try decoder.decode(T.self, from: data)
    } catch {
        fatalError("Couldn't parse \(filename) as \(T.self):\n\(error)")
    }
}

final class ImageStore {
    typealias _ImageDictionary = [String: CGImage]
    fileprivate var images: _ImageDictionary = [:]

    fileprivate static var scale = 2

    static var shared = ImageStore()

    func image(name: String) -> Image {
        let index = _guaranteeImage(name: name)

        return Image(images.values[index], scale: CGFloat(ImageStore.scale), label: Text(name))
    }

    static func loadImage(name: String) -> CGImage {
        guard
            let url = Bundle.main.url(forResource: name, withExtension: "png"),
            let imageSource = CGImageSourceCreateWithURL(url as NSURL, nil),
            let image = CGImageSourceCreateImageAtIndex(imageSource, 0, nil)
        else {
            fatalError("Couldn't load image \(name).jpg from main bundle.")
        }
        return image
    }

    fileprivate func _guaranteeImage(name: String) -> _ImageDictionary.Index {
        if let index = images.index(forKey: name) { return index }

        images[name] = ImageStore.loadImage(name: name)
        return images.index(forKey: name)!
    }
}


像以前一样创建
UIImage

let imageModel = UIImage(contentsOfFile: imgPath)
并在
正文
中将其用作
图像
视图的模型

Image(uiImage: imageModel ?? UIImage())

我把let-imageModel=UIImage(contentsOfFile:imgPath)放在哪里,所以我做了一个函数``func unwapit(file:String)->UIImage{if-let-imgPath=Bundle.main.path(forResource:file,of type:“png”){if-let-imageModel=UIImage(contentsOfFile:imgPath){return-imageModel}返回UIImage(imageLiteralResourceName:“MOS_SHB_10”)}``然后在正文中使用``Image(UIImage:Unwapit(file:imageslide.imagename))``调用它,但这不起作用,内存仍然不足
//PageViewController.swift

import SwiftUI
import UIKit

struct PageViewController: UIViewControllerRepresentable {
    var controllers: [UIViewController]
    @Binding var currentPage: Int

    func makeCoordinator() -> Coordinator {
        Coordinator(self)
    }

    func makeUIViewController(context: Context) -> UIPageViewController {
         let pageViewController = UIPageViewController(
             transitionStyle: .scroll,
             navigationOrientation: .horizontal)
        pageViewController.dataSource = context.coordinator
        pageViewController.delegate = context.coordinator

         return pageViewController
     }


    func updateUIViewController(_ pageViewController: UIPageViewController, context: Context) {
        pageViewController.setViewControllers(
             [controllers[currentPage]], direction: .forward, animated: true)
    }


    class Coordinator: NSObject, UIPageViewControllerDataSource, UIPageViewControllerDelegate {
        var parent: PageViewController

        init(_ pageViewController: PageViewController) {
            self.parent = pageViewController
        }


    func pageViewController(
        _ pageViewController: UIPageViewController,
        viewControllerBefore viewController: UIViewController) -> UIViewController?
    {
        guard let index = parent.controllers.firstIndex(of: viewController) else {
            return nil
        }
        if index == 0 {
            return parent.controllers.last
        }
        return parent.controllers[index - 1]
    }

    func pageViewController(
        _ pageViewController: UIPageViewController,
        viewControllerAfter viewController: UIViewController) -> UIViewController?
    {
        guard let index = parent.controllers.firstIndex(of: viewController) else {
            return nil
        }
        if index + 1 == parent.controllers.count {
            return parent.controllers.first
        }
        return parent.controllers[index + 1]

    }

    func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {
        if completed,
            let visibleViewController = pageViewController.viewControllers?.first,
            let index = parent.controllers.firstIndex(of: visibleViewController)
        {
            parent.currentPage = index
        }
    }
}

}


//pageview.swift 
import SwiftUI

struct PageView<Page: View>: View {
    var viewControllers: [UIHostingController<Page>]

    @State var currentPage = 0

    init(_ views: [Page]) {
        self.viewControllers = views.map { UIHostingController(rootView: $0) }
    }

    var body: some View {
         PageViewController(controllers: viewControllers, currentPage: $currentPage)
    }
}

struct PageView_Previews: PreviewProvider {
    static var previews: some View {

        PageView(imageData.map {ContentView(imageslide: $0)})
    }
}
   {
      "Imageslide":{
         "imagename":"MOS_SHB_1",
         "id":1001,
         "noButtons":0
      }
   },
   {
      "Imageslide":{
         "imagename":"MOS_SHB_2",
         "id":1002,
         "noButtons":0
      }
   },
   {
      "Imageslide":{
         "imagename":"MOS_SHB_3",
         "id":1003,
         "noButtons":1,
         "buttoninfo":[
            {
               "text":"The two halves of the arch touched for the first time. Workers riveted both top and bottom sections of the arch together, and the arch became self-supporting, allowing the support cables to be removed. On 20 August 1930 the joining of the arches was celebrated by flying the flags of Australia and the United Kingdom from the jibs of the creeper cranes.",
               "coords":[
                  -150,
                  220,
                  200,
                  200
               ]
            }
         ]
      }
   },
let imageModel = UIImage(contentsOfFile: imgPath)
Image(uiImage: imageModel ?? UIImage())