Ios 表视图单元格按钮关闭是否需要弱自我
在试图避免保留周期时,是否有必要在UITableViewCell按钮操作中使用中的Ios 表视图单元格按钮关闭是否需要弱自我,ios,swift,uitableview,uibutton,retain-cycle,Ios,Swift,Uitableview,Uibutton,Retain Cycle,在试图避免保留周期时,是否有必要在UITableViewCell按钮操作中使用中的[弱自我]?例如: 在ViewController的cellForRow cell.buttonAction = { (cell) [weak self] in self.someFunction() } 在TableViewCell类中 var buttonAction: ((UITableViewCell) -> Void)? @IBAction func buttonPressed(_ s
[弱自我]?例如:
在ViewController的cellForRow
cell.buttonAction = { (cell) [weak self] in
self.someFunction()
}
在TableViewCell类中
var buttonAction: ((UITableViewCell) -> Void)?
@IBAction func buttonPressed(_ sender: Any) {
buttonAction?(self)
}
是的,在这种情况下,有必要使用无主
或弱
来捕获自身
- 您的视图控制器很可能对
UITableView
- 表视图对其
UITableViewCells
和
- 每个单元格都强烈引用您的
按钮操作
闭包
直接使用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)
}
}
您将获得以下输出:
现在,在没有弱的情况下显示相同的视图控制器,您将看到没有输出,这意味着不会调用deinit
函数,并且对象保留在内存中。是的,在这种情况下,有必要使用无主
或弱
来捕获自身
- 您的视图控制器很可能对
UITableView
- 表视图对其
UITableViewCells
和
- 每个单元格都强烈引用您的
按钮操作
闭包
直接使用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)
}
}
您将获得以下输出:
现在,在没有弱的情况下显示相同的视图控制器,您将看到没有输出,这意味着不会调用deinit
函数,并且对象保留在内存中。如果您不使用tableviewcell的对象,并且只希望在单元格上执行操作,请执行此操作
var buttonAction: (() -> Void)?
@IBAction func buttonPressed(_ sender: Any) {
buttonAction?()
}
在牢房里用这个
cell.buttonAction = { [weak self] in
self?.someFunction()
}
对于check-retain循环,我通常使用这个选项来检查内存是否被保留。
如果您不使用tableviewcell的对象,并且只希望对单元格执行操作,请执行此操作
var buttonAction: (() -> Void)?
@IBAction func buttonPressed(_ sender: Any) {
buttonAction?()
}
在牢房里用这个
cell.buttonAction = { [weak self] in
self?.someFunction()
}
对于check-retain循环,我通常使用这个选项来检查内存是否被保留。
需要考虑的关键问题是:
var buttonAction: ((UITableViewCell) -> Void)?
您提供在实例属性中长期存储函数
现在想想谁指谁/拥有谁。视图控制器拥有自己的视图,该视图是或拥有拥有单元格的表视图。同时,细胞也拥有这一功能。如果函数强烈引用我刚才提到的任何对象,那就是一个保留循环。这是一个经典的保留周期,是如何进行保留周期的绝对模型
[我想补充一句关于如何测试这些东西的话。有一种非常便宜且简单的方法:将视图控制器包装在导航控制器中,再加上一个空白的根视图控制器,这样你就可以将视图控制器推到它上。在视图控制器中实现deinit
。现在运行应用程序,推送视图控制器,玩with它一点,然后用后退按钮弹出它。如果没有调用deinit
,则您有一个保留周期。]需要考虑的关键行是:
var buttonAction: ((UITableViewCell) -> Void)?
您提供在实例属性中长期存储函数
现在想想谁引用了谁/拥有了谁。视图控制器拥有自己的视图,或者拥有拥有单元格的表视图。同时,单元格拥有函数。如果函数强烈引用了我刚才提到的任何对象,那就是一个保留循环。这是一个经典的保留循环,是保留循环的绝对模式。
[我想补充一句关于如何测试这些东西的话。有一种非常便宜且简单的方法:将视图控制器包装在导航控制器中,再加上一个空白的根视图控制器,这样你就可以将视图控制器推到它上。在视图控制器中实现deinit
。现在运行应用程序,推送视图控制器,玩with它一点,然后用后退按钮弹出它。如果未调用deinit
,则您有一个保留周期。]为什么不在内存图调试器中查看它,这样你就可以自己查看?这是一个很好的学习机会为什么不在内存图调试器中查看它,这样你就可以自己查看?这是一个很好的学习机会。你能用一点代码写下当点击后退按钮时如何测试vc从导航vc中脱离的位置吗你更喜欢这种测试的扩展,或者像你说的那样写几行代码。我应该为我的问题问一个新问题,还是在这里就可以了?你能用一点代码写下当点击后退按钮时你是如何测试vc从导航vc中分离的吗?你更喜欢这种测试的扩展,还是像你说的那样写几行代码。我应该为我的问题问一个新问题,还是在这里可以?