gpt4 book ai didi

ios - 强引用循环 : closures vs methods

转载 作者:搜寻专家 更新时间:2023-11-01 06:48:28 24 4
gpt4 key购买 nike

我有一个包含名为 TableViewControllerUITableViewController 的项目。因为我希望我的 UITableViewDataSource 协议(protocol)声明在我的 TableViewController 声明之外,所以我设置了以下代码(受 Objc.io Lighter View Controllers 启发):

TableView Controller :

class TableViewController: UITableViewController {

let array = [["1"], ["2", "3", "4"], ["5", "6"]]
var dataSource: DataSource!


override func viewDidLoad() {
super.viewDidLoad()

dataSource = DataSource(array: array, configureCellBlock: { (cell, item) in
cell.textLabel.text = item
})
tableView.dataSource = dataSource
}

override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}

deinit {
println("Quit TVC")
}

}

数据源:

class DataSource: NSObject, UITableViewDataSource {

let array: [[String]]
typealias TableViewCellConfigureBlock = (cell: UITableViewCell, item: String) -> ()
var configureCellBlock: TableViewCellConfigureBlock


init(array: [[String]], configureCellBlock: TableViewCellConfigureBlock) {
self.array = array
self.configureCellBlock = configureCellBlock

super.init()
}

func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return array.count
}

func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return array[section].count
}

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as UITableViewCell

let data = array[indexPath.section][indexPath.row]
configureCellBlock(cell: cell, item: data)

return cell
}

deinit {
println("Quit DataSource")
}

}

这很好用。但是现在,我想用一个方法替换 configureCellBlock 闭包。所以我将我的 TableViewController 代码更改为:

class TableViewController: UITableViewController {

let array = [["1"], ["2", "3", "4"], ["5", "6"]]
var dataSource: DataSource!


override func viewDidLoad() {
super.viewDidLoad()

dataSource = DataSource(array: array, configureCellBlock: formatCell)
tableView.dataSource = dataSource
}

func formatCell(cell: UITableViewCell, item: String) -> () {
cell.textLabel.text = item
}

override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}

deinit {
println("Quit TVC")
}

}

现在的问题很明显:如果我运行这段代码,TableViewControllerDataSource 永远不会因为强引用循环而被释放。

我一直在尝试将我的 dataSource 声明更改为 weak var dataSource: DataSource!unowned var dataSource: DataSource 但都没有我最近的尝试奏效了。

如何用方法替换我的 configureCellBlock 闭包?我是否必须使用协议(protocol)委托(delegate)模式才能这样做?它会是什么样子?

最佳答案

问题是对 formatCell 的引用隐含了对 self 的引用。这不是通过使数据源变弱来解决的(你肯定希望那里有一个强引用),而是确保数据源中的 block 变量不维护返回 View Controller 的强引用。因此,您可以将 [unowned self] 添加到闭包的开头:

dataSource = DataSource(array: array) {
[unowned self] cell, item in

self.formatCell(cell, item: item)
return
}

关于ios - 强引用循环 : closures vs methods,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26573377/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com