简体   繁体   中英

How to convert/cast from a protocol to a class in swift?

Pretty simple, I'd have thought; I just want to check if a variable is a class and cast it to one if possible.

For example:

var cellProtocol:MyTableViewCellProtocol? = nil
cellProtocol = tableView.dequeueReusableCellWithIdentifier(kCellIdentifier, forIndexPath: indexPath) as MyTableViewCell

how do I explicitly cast the cell to a UITableViewCell?

Inheritance as follows:

class MyTableViewCell: UITableViewCell, MyTableViewCellProtocol {
//....
}


@objc protocol MyTableViewCellProtocol: class, NSObjectProtocol {
    func configureCell()
}

That protocol definition was the result of me trying to solve this problem. My original one didn't have the @ objc tag in it or the class -only identifier.

I tried a few things to make the cast happen but it has not worked:

    var cellToReturn = cellProtocol as UITableViewCell

This doesn't compile because UITableViewCell does not inherit explicitly from MyTableViewCellProtocol .

    var cellToReturn = cellProtocol as AnyObject as UITableViewCell

This fails at runtime because cellProtocol fails to cast into AnyObject .

I haven't been able to get the unsafeBitCast thing to work yet but that's another possibility I've been exploring.

Just a note, that this DOES work in Obj-C.

id<MyTableViewCellProtocol> cellProtocol = cell;
[cellProtocol configureCell];
UITableViewCell *cellCast = (UITableViewCell *)cellProtocol;

This gives me no errors and runs fine.

With Swift 1.2 / Xcode 6.3 Beta, this compiles:

var cellToReturn = cellProtocol as! UITableViewCell

As of Swift 1.1, You have to cast it to AnyObject or Any , then UITableViewCell . I think this was a kind of bug.

var cellToReturn = cellProtocol as AnyObject as UITableViewCell

ADDED: It turns out that it's a problem of Optional

In this case, cellProtocol is MyTableViewCellProtocol? . you have to unwrap it first, then cast.

Try:

var cellToReturn = cellProtocol! as AnyObject as UITableViewCell
//                             ^

If you want it to only be a MyTableViewCellProtocol , you should use that in the as clause. If you want conditional casting, use a if let .

if let cellProtocol = <dequeue> as? MyTableViewCellProtocol {
  // You're an object that conforms to MyTableViewCellProtocol.
  if let mycell = cellProtocol as? MyTableViewCell {
    // You're a MyTableViewCell object
    if let cell = cell as? UITableViewCell {
      // You're a UITableViewCell object
    }
  }
}

Keep in mind that you can only check protocol conformance on protocols specified as @objc (but you've already done that).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM