Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does Swift UITableViewController template use optionals arguments in tableView cellForRowAtIndexPath method?

Tags:

If you create new UITableViewController class, you will see commented method for override:

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

You can uncomment method and it will not work because of error

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

The reason is: tableView is defined as optional type "UITableView?" and you have to unwrap tableView before call the method. For example like this:

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

But we can make them implicitly unwrapped optionals and use tableView without !

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

The question is: why does the xcode define them as optionals? Does it have any reason or advatages vs implicitly unwrapped optionals? Can be we sure, that this method always gets not-nill values?

Also we will have another errors

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? 

We can fix it by adding as UITableViewCell to the end like this:

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

I have no idea why doesn't template look like this by default:

/* 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 } */ 
like image 611
John Kakon Avatar asked Jun 06 '14 09:06

John Kakon


1 Answers

Actually this is the correct way to use the delegate method.

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {     let cell = tableView.dequeueReusableCellWithIdentifier("CELL_ID", forIndexPath: indexPath)     cell.textLabel.text = "aaaa"     return cell  } 
like image 164
Ryan Avatar answered Oct 04 '22 06:10

Ryan