设置表格视图单元格的样式为基本,标识符为故事板中的单元格,代码如下:
import UIKit class TableViewController: UITableViewController { var items: [String]! override func viewDidLoad() { super.viewDidLoad() items = ["first","second","third"] } override func numberOfSectionsInTableView(tableView: UITableView) -> Int { return 1 } override func tableView(tableView: UITableView,numberOfRowsInSection section: Int) -> Int { return items.count } override func tableView(tableView: UITableView,cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { // either works fine let cell = tableView.dequeueReusableCellWithIdentifier("Cell")! // let cell = tableView.dequeueReusableCellWithIdentifier("Cell",forIndexPath: indexPath) cell.textLabel?.text = items[indexPath.row] return cell } }
很简单,但是当我将tableView:cellForRowAtIndexPath:方法分别更改为1,2,3,4个时:
情况1:
override func tableView(tableView: UITableView,cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { var cell = tableView.dequeueReusableCellWithIdentifier("Cell",forIndexPath: indexPath) cell = tableView.dequeueReusableCellWithIdentifier("Cell",forIndexPath: indexPath) cell.textLabel?.text = items[indexPath.row] return cell }
案例2:
override func tableView(tableView: UITableView,forIndexPath: indexPath) cell = tableView.dequeueReusableCellWithIdentifier("Cell")! cell.textLabel?.text = items[indexPath.row] return cell }
案例3:
override func tableView(tableView: UITableView,cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { var cell = tableView.dequeueReusableCellWithIdentifier("Cell")! cell = tableView.dequeueReusableCellWithIdentifier("Cell",forIndexPath: indexPath) cell.textLabel?.text = items[indexPath.row] return cell }
案例4:
override func tableView(tableView: UITableView,cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { var cell = tableView.dequeueReusableCellWithIdentifier("Cell")! cell = tableView.dequeueReusableCellWithIdentifier("Cell")! cell.textLabel?.text = items[indexPath.row] return cell }
案例1,2(不起作用):
案例3,4(工作正常):
如何解释?我认为从另一个角度理解这两种方法确实很有帮助,任何意见都是受欢迎的.
解决方法
(我修改了cellForRowAtIndexPath代码,如下所示:
override func tableView(tableView: UITableView,cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { var cell = tableView.dequeueReusableCellWithIdentifier("plainCell",forIndexPath: indexPath) cell.textLabel!.text = "First cell for row \(indexPath.row)" cell = tableView.dequeueReusableCellWithIdentifier("plainCell",forIndexPath: indexPath) cell.textLabel!.text = "Second cell for row \(indexPath.row)" print("Cell being returned is \(cell)") return cell }
为每个单元格指定不同的文本标签.)在情况3和4中,首先调用(“单元格”)版本,表视图每行只有一个单元格.
为什么不同的行为?如果您创建UITableViewCell的自定义子类并在故事板中使用它,则可以覆盖各种方法并添加print()语句以查看正在发生的事情.特别是awakeFromNib,didMoveToSuperView和deinit.发生的情况是,在情况1和2中,创建了第一个单元格(awakeFromNib)并立即将其添加(didMoveToSuperView)到superview,可能是表视图或其子视图之一.在情况3和4中,创建了第一个单元格但未添加到超级视图中.相反,一段时间后,细胞被解除分配(deinit).
(注意,如果第二个单元格使用(“Cell”,forIndexPath:indexPath)版本出列,它也会立即添加到superview.但是,如果第二个单元格使用(“Cell”)版本出列,则它是仅在cellForRowAtIndexPath方法返回后才添加到superview.)
因此,关键的区别在于(“Cell”,forIndexPath:indexPath)版本导致单元格被立即添加到表视图中,甚至在cellForRowAtIndexPath完成之前.这在您提到的问题/答案中暗示,因为它表明出列单元格的大小正确.
一旦添加到superview,第一个单元格就不能被释放,因为它的superview仍然有一个强引用.如果单元格以(“单元格”)版本出列,则它们不会被添加到超级视图中,因此一旦重新分配单元格变量,就没有对它们的强引用,因此它们被解除分配.
希望这一切都有意义.