ios - 向集合视图单元添加集合视图会导致内存增长
问题描述
我创建了一个 CollectionView,并在每个 CollectionViewCell 上创建了一个 CollectionView。下面我包含了位于 MainCollectionView 单元格内的 collectionView 的代码。每次我将单元格从一个 collectionView 滑到另一个时,内存都会增长,并且在删除一个单元格后,内存不会被释放。我读过collectionView 对其布局有很强的参考 我不确定这是否是原因。我执行这个错误吗?谢谢你的帮助。
主视图控制器
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: FullPageCell.reuseIdentifier, for: indexPath) as? FullPageCell else{
assertionFailure("Fatal Error FullPageCell not dequed")
return UICollectionViewCell()
}
cell.backgroundColor = UIColor.green
cell.cellTappedDelegate = self
return cell
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return numberOfPages
}
func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
if let cell = cell as? FullPageCell{
cell.setUpCollectionView()
}
}
func collectionView(_ collectionView: UICollectionView, didEndDisplaying cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
if let cell = cell as? FullPageCell{
cell.collectionView = nil
}
}
子单元集合视图
static var reuseIdentifier: String = "FullPageCell"
var collectionView:UICollectionView? = nil
weak var cellTappedDelegate:CellTappedDelegate?
var image:UIImage = #imageLiteral(resourceName: "Image")
override init(frame: CGRect) {
super.init(frame:frame)
self.setUpCollectionView()
}
func setUpCollectionView(){
let view = self.contentView
let layout = UICollectionViewFlowLayout()
layout.minimumLineSpacing = 1
layout.minimumInteritemSpacing = 1
layout.scrollDirection = .vertical
layout.itemSize = CGSize(width: (view.bounds.width - 2)/3, height: (view.bounds.width - 2)/3)
self.collectionView = UICollectionView(frame:view.bounds, collectionViewLayout: layout)
guard let collectionView = collectionView else{
return
}
collectionView.dataSource = self
collectionView.delegate = self
collectionView.register(SmallCell.self, forCellWithReuseIdentifier: SmallCell.reuseIdentifier)
collectionView.backgroundColor = UIColor.white
self.collectionView?.isPagingEnabled = true
view.addSubview(collectionView)
collectionView.translatesAutoresizingMaskIntoConstraints = false
collectionView.topAnchor.constraint(equalTo: view.topAnchor, constant: 0).isActive = true
collectionView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 0).isActive = true
collectionView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: 0).isActive = true
collectionView.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: 0).isActive = true
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: SmallCell.reuseIdentifier, for: indexPath) as? SmallCell else{
assertionFailure("Fatal Error FullPageCell not dequed")
return UICollectionViewCell()
}
cell.backgroundColor = UIColor.yellow
cell.imageView.image = self.image
return cell
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 1000
}
解决方案
不确定这个游乐场是否反映了您正在尝试做的事情,但它会向您展示如何避免每次都创建 collectionView:
import UIKit
import PlaygroundSupport
class InnerCell: UICollectionViewCell {
let textLabel = UILabel()
override init(frame: CGRect) {
super.init(frame: frame)
contentView.backgroundColor = .white
textLabel.layer.borderColor = UIColor.gray.cgColor
textLabel.layer.borderWidth = 1
textLabel.textAlignment = .center
textLabel.translatesAutoresizingMaskIntoConstraints = false
contentView.addSubview(textLabel)
NSLayoutConstraint.activate([
textLabel.leadingAnchor.constraint(equalTo: contentView.leadingAnchor),
textLabel.trailingAnchor.constraint(equalTo: contentView.trailingAnchor),
textLabel.topAnchor.constraint(equalTo: contentView.topAnchor),
textLabel.bottomAnchor.constraint(equalTo: contentView.bottomAnchor)
])
}
required init?(coder aDecoder: NSCoder) {
fatalError()
}
}
class Cell: UICollectionViewCell, UICollectionViewDataSource {
var data: [Int]! = [] {
didSet {
collectionView.reloadData()
}
}
private let collectionView: UICollectionView
override init(frame: CGRect) {
let layout = UICollectionViewFlowLayout()
layout.minimumLineSpacing = 1
layout.minimumInteritemSpacing = 1
layout.itemSize = .init(width: 220, height: 220)
collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
super.init(frame: frame)
collectionView.isPagingEnabled = true
collectionView.backgroundColor = .white
collectionView.register(InnerCell.self, forCellWithReuseIdentifier: "Cell")
collectionView.dataSource = self
collectionView.translatesAutoresizingMaskIntoConstraints = false
contentView.addSubview(collectionView)
NSLayoutConstraint.activate([
collectionView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor),
collectionView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor),
collectionView.topAnchor.constraint(equalTo: contentView.topAnchor),
collectionView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor)
])
}
required init?(coder aDecoder: NSCoder) {
fatalError()
}
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return data.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) as! InnerCell
cell.textLabel.text = String(data[indexPath.item])
return cell
}
}
class VC: UICollectionViewController, UICollectionViewDelegateFlowLayout {
let data = [
0: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14],
1: [6, 4],
2: [5, 5, 5, 5, 6],
3: [1, 2, 3, 4, 5, 6, 7]
]
override init(collectionViewLayout layout: UICollectionViewLayout) {
super.init(collectionViewLayout: layout)
collectionView.isPagingEnabled = true
collectionView.register(Cell.self, forCellWithReuseIdentifier: "Cell")
}
required init?(coder aDecoder: NSCoder) {
fatalError()
}
override func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return data.count
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) as! Cell
cell.data = data[indexPath.item]
return cell
}
public func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return collectionView.bounds.size
}
}
let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .horizontal
layout.minimumLineSpacing = 0
PlaygroundPage.current.liveView = VC(collectionViewLayout: layout)
推荐阅读
- ruby-on-rails - Rails 用户部分作为变量
- php - php - Mysql Query 工作除了一个过滤器
- c# - 关于加速硬盘备份代码的建议
- java - 在 Java 中 String hashCode() 的旧 impl 中跳过字符背后的想法是什么
- python - 如何运行托管在 a2hosting 上的 Flask 应用程序?
- matlab - 如何优化此字符串替换代码
- angular7 - 两种语言 Angular 构建,一种正常,一种有错误
- c# - C# - 线程任务 - Dotnet 4.x 中的最佳实践
- nix - 如何将我的 nix 环境重置为原始用户配置文件?
- c# - MailAddress 到正确的传真服务器工作不正常