为什么Swift UITableViewController模板在tableView cellForRowAtIndexPath方法中使用可选参数?

如果你创build了新的UITableViewController类,你会看到override的注释方法:

/* override func tableView(tableView: UITableView?, cellForRowAtIndexPath indexPath: NSIndexPath?) -> UITableViewCell? { let cell = tableView.dequeueReusableCellWithIdentifier("reuseIdentifier", forIndexPath: indexPath) // Configure the cell... return cell } */ 

您可以取消注释方法,并且由于错误而不起作用

 'UITableView?' does not have a member named 'dequeueReusableCellWithIdentifier' 

原因是:tableView被定义为可选types“ UITableView? ”,你必须在调用方法之前解开tableView。 比如像这样:

 let cell = tableView!.dequeueReusableCellWithIdentifier("reuseIdentifier", forIndexPath: indexPath) 

但是我们可以让它们隐式地解包选项并且不使用tableView

 override func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! { let cell = tableView.dequeueReusableCellWithIdentifier("reuseIdentifier", forIndexPath: indexPath) return cell } 

问题是 :为什么xcode将它们定义为可选项? 它是否有任何理由或build议vs隐含的解包选项? 可以肯定的是,这种方法总是得不到 – 价值?

另外我们会有另一个错误

 Constant 'cell' inferred to have type 'AnyObject!', which may be unexpected Type 'AnyObject!' cannot be implicitly downcast to 'UITableViewCell'; did you mean to use 'as' to force downcast? 

我们可以通过添加UITableViewCell来解决这个问题,就像这样:

 let cell = tableView.dequeueReusableCellWithIdentifier("reuseIdentifier", forIndexPath: indexPath) as UITableViewCell 

我不知道为什么不默认模板看起来像这样:

 /* override func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! { let cell = tableView.dequeueReusableCellWithIdentifier("reuseIdentifier", forIndexPath: indexPath) as UITableViewCell //or your custom class // Configure the cell... return cell } */ 

是的,这很奇怪。 事实上,如果你擦除模板提供的方法,并开始input每一个,Xcode自动完成将build议方法隐式解包可选参数,如

 tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! 

我猜这些模板目前是错误的,稍后可能会被修复,因为模板版本在手工input时甚至没有提供。 如果将它们留在那里,它们确实会被正常调用,只要您根据需要正确打开参数,它就会工作。

看到这个问题更多的讨论。

其实这是使用委托方法的正确方法。

 func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCellWithIdentifier("CELL_ID", forIndexPath: indexPath) cell.textLabel.text = "aaaa" return cell }