Сейчас я работаю над приложением SwiftUI, которое отображает медиафайлы в сетке с помощью LazyVGrid в GalleryView, где в каждой строке будет по 3 медиафайла. Медиа-файлы загружаются из кэша приложения, а не из приложения «Фото» пользователя. Когда пользователь прокручивает вниз, чтобы увидеть больше медиаданных, медиафайлы лениво загружаются в память, а те, которые скрыты от просмотра, не освобождаются из памяти, поскольку LazyVGrid не имеет встроенного механизма освобождения памяти. Проблемы с памятью становятся более очевидными (
Код: Выделить всё
n>10
Код: Выделить всё
struct GalleryView: View {
@Binding var mediaFiles: [Media]
var body: some View {
GeometryReader { geometry in
ScrollView {
let width = geometry.size.width / 3 - 10
let gridItemLayout = [GridItem(.fixed(width)), GridItem(.fixed(width)), GridItem(.fixed(width))]
LazyVGrid(columns: gridItemLayout, spacing: 10) {
ForEach(mediaFiles, id: \.id) { media in
if let image = media.image {
Image(uiImage: image)
.resizable()
.scaledToFit()
.frame(width: width)
} else if let videoURL = media.videoURL {
// Display video thumbnail here
}
}
}
}
}
}
}
struct Media: Identifiable {
let id = UUID()
let creationTime: Date
var image: UIImage?
var videoURL: URL?
}
Код: Выделить всё
struct CollectionView: UIViewControllerRepresentable {
typealias UIViewControllerType = UICollectionViewController
@Binding var mediaFiles: [Media]
var width: CGFloat
func makeUIViewController(context: Context) -> UICollectionViewController {
let layout = UICollectionViewFlowLayout()
layout.itemSize = CGSize(width: width / 3, height: width / 3)
layout.minimumLineSpacing = 10
layout.minimumInteritemSpacing = 10
let collectionViewController = UICollectionViewController(collectionViewLayout: layout)
collectionViewController.collectionView?.register(MediaCell.self, forCellWithReuseIdentifier: "cell")
collectionViewController.collectionView?.backgroundColor = .white
return collectionViewController
}
func updateUIViewController(_ uiViewController: UICollectionViewController, context: Context) {
uiViewController.collectionView?.dataSource = context.coordinator
uiViewController.collectionView?.delegate = context.coordinator
uiViewController.collectionView?.reloadData()
}
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
class Coordinator: NSObject, UICollectionViewDataSource, UICollectionViewDelegate {
var parent: CollectionView
init(_ parent: CollectionView) {
self.parent = parent
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return parent.mediaFiles.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! MediaCell
let media = parent.mediaFiles[indexPath.row]
if let image = media.image {
cell.imageView.image = image
}
return cell
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
// Handle selection here
}
}
}
Код: Выделить всё
CollectionView(mediaFiles: $mediaFiles, width: width)
.frame(width: geometry.size.width, height: geometry.size.height)
.onAppear {
model.loadMediaFiles()
if let lastMediaIndex = mediaFiles.indices.last {
scrollView.scrollTo(lastMediaIndex, anchor: .bottom)
}
}
Is there a simple and intuitive way to deal with this absence of memory deallocation issue with LazyVGrid? If a UIKit implementation is the best approach, could someone help identify what’s wrong with my current UIKit code that’s causing the GalleryView to display a blank screen?
Источник: https://stackoverflow.com/questions/781 ... edia-files