如何解决表格视图单元格按钮关闭是否需要弱自我
在尝试避免保留周期时,是否有必要在UITableViewCell按钮操作中使用[weak self] in
?示例:
在ViewController的cellForRow
cell.buttonAction = { (cell) [weak self] in
self.someFunction()
}
在TableViewCell类中
var buttonAction: ((UITableViewCell) -> Void)?
@IBAction func buttonpressed(_ sender: Any) {
buttonAction?(self)
}
解决方法
要考虑的关键是:
var buttonAction: ((UITableViewCell) -> Void)?
您打算在实例属性中长期存储功能。
现在考虑谁指/拥有谁。视图控制器拥有其视图,该视图或拥有拥有单元格的表视图。同时,细胞拥有功能。如果函数强烈引用我刚才提到的任何对象,则那是一个保留周期。这是一个经典保留周期,这是保留周期如何形成的绝对模型。
[我想补充一下我如何测试这些东西。有一种非常便宜和简便的方法:将视图控制器包装在导航控制器中,再加上一个空白的根视图控制器,以便可以将视图控制器推入。在您的视图控制器中实现deinit
。现在运行该应用程序,推动您的视图控制器,进行一些操作,然后使用“后退”按钮将其弹出。如果未调用deinit
,则您有一个保留周期。]
是的,在这种情况下,必须使用unowned
或weak
来捕获self
。
- 您的视图控制器很可能会强烈引用
UITableView
- 表视图对其
UITableViewCells
和 有很强的引用
- 每个单元格都强烈引用您的
buttonAction
结束符。
直接使用self具有保留周期的作用。
这实际上很容易测试。尝试提供以下视图控制器并将其关闭:
class TestTableViewCell: UITableViewCell {
var closure: (() -> Void)?
deinit {
print("TestTableViewCell deinit!")
}
}
class TestTableViewController: UITableViewController {
override func viewDidLoad() {
super.viewDidLoad()
tableView.register(TestTableViewCell.self,forCellReuseIdentifier: "TestTableViewCellIdentifier")
}
deinit {
print("TestTableViewController deinit!")
}
override func tableView(_ tableView: UITableView,numberOfRowsInSection section: Int) -> Int {
return 1
}
override func tableView(_ tableView: UITableView,cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "TestTableViewCellIdentifier",for: indexPath) as! TestTableViewCell
cell.closure = { [weak self] in
guard let self = self else { return }
self.testFunction()
}
return cell
}
func testFunction() {}
}
// Test present
let controller = TestTableViewController()
present(controller,animated: true) {
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
self.dismiss(animated: true)
}
}
您将获得以下输出:
TestTableViewController deinit! TestTableViewCell deinit!
现在呈现不带弱点的相同视图控制器,您将看到没有输出,这意味着deinit
函数不会被调用,并且对象将保留在内存中。
如果您不使用tableviewcell的对象,而只想对单元格执行操作,请执行此操作。
var buttonAction: (() -> Void)?
@IBAction func buttonPressed(_ sender: Any) {
buttonAction?()
}
在cellForRow上使用它,
cell.buttonAction = { [weak self] in
self?.someFunction()
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。