Swift - what is downcasting? why do i need to down

2019-05-04 07:37发布

问题:

The code below is to show the name of the cells in UItableview.

 override func tableView(tableView: UITableView,
        cellForRowAtIndexPath
        indexPath: NSIndexPath) -> UITableViewCell {

        let cell = tableView.dequeueReusableCellWithIdentifier("Cell")
            as UITableViewCell

        cell.textLabel!.text = "Spring \(indexPath.row + 1)"

        return cell
}

There is a compiling error and Xcode suggests me to change the line 'as' into 'as!'-

    let cell = tableView.dequeueReusableCellWithIdentifier("Cell")
        as! UITableViewCell

May someone explains what is downcast and why do we need to downcast in this case?

回答1:

OK..lets make it very simple.

On the line:

let cell = tableView.dequeueReusableCellWithIdentifier("Cell")

You are accessing the method dequeueReusableCellWithIdentifier of tableView, if you look at the documentation you can see the return type is AnyObject?.

Now suppose you want to access the textLabel property as

cell.textLabel!.text = "Spring \(indexPath.row + 1)"

You cannot do it..because there is no any textlabel on AnyObject the type.

So, you are downcasting to force compiler more specific class, UITableViewCell, as below because later you are trying to access text label property:

let cell = tableView.dequeueReusableCellWithIdentifier("Cell") as! UITableViewCell


回答2:

Because -dequeueReusableCellWithIdentifier: returns AnyObject (id in Objective-C). Swift needs you to force downcast because AnyObject can be any object and by force casting, you're telling the compiler to disregard the current type and force cast to a more specific object down the inheritance line.



回答3:

As it reads in the Official Swift Documentation, under downcasting:

A constant or variable of a certain class type may actually refer to an instance of a subclass behind the scenes. Where you believe this is the case, you can try to downcast to the subclass type with a type cast operator (as? or as!).

Use the forced form of the type cast operator (as!) only when you are sure that the downcast will always succeed. This form of the operator will trigger a runtime error if you try to downcast to an incorrect class type.

I hope this may answer your question ^_^



回答4:

As @Schemetrical said -dequeueReusableCellWithIdentifier: return AnyObject but -tableView:cellForRowAtIndexPath: need UITableViewCell to be returned.

override func tableView(tableView: UITableView,
        cellForRowAtIndexPath
        indexPath: NSIndexPath) -> UITableViewCell {
...
}

So if you return cell without downcast it, that won't match the method signature.