检查segue标识符而不是使用失败类型强制转换有什么好处吗?

时间:2022-09-06 12:35:14

When we implement a prepareForSegue:sender: method in a UIViewController subclass that has multiple segues, one idiom in Objective-C is to assign an identifier to the segue in the storyboard, and wrap the logic in prepareForSegue:sender: in an if statement that inspects the segue identifier. For example:

当我们实现prepareForSegue:sender:在一个具有多个segue的UIViewController子类中的方法时,Objective-C中的一个习惯用法是在故事板中为segue分配一个标识符,并在prepareForSegue中包装逻辑:sender:在一个if语句中检查segue标识符。例如:

if segue.identifier == "destinationA"
    // prepare destinationA stuff
else if segue.identifier == "destinationB"
    // prepare destinationB stuff
...

In Swift, we're essentially forced by the API to use type casting when obtaining the instance of the destination view controller. Since this can fail gracefully, my question is should we go ahead and rely on optional binding with conditional type casting (as?) or should we still rely on an if statement?

在Swift中,在获取目标视图控制器的实例时,API实际上迫使我们使用类型转换。由于这可能会优雅地失败,我的问题是,我们应该继续使用带有条件类型强制转换(as?)的可选绑定,还是应该继续使用if语句?

For example, where possible, should we favor the succinctness of relying on just type casting:

例如,在可能的情况下,我们是否应该倾向于仅依靠类型铸造的简洁性:

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    if let destination = segue.destinationViewController as? DestinationAController {
        // prepare stuff for Destination A
    } else if let destination = segue.destinationViewController as? DestinationBController {
        // prepare stuff for Destination B
    }
}

Or is there a benefit in still wrapping everything in an if statement like we did in Objective-C:

还是像Objective-C一样,把所有东西都包装在if语句中有什么好处?

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    if segue.identifier == "destinationA" {
        if let destination = segue.destinationViewController as? DestinationAController {
            // prepare stuff for Destination A
        }
    } else if segue.identifier == "destinationB" {
        if let destination = segue.destinationViewController as? DestinationBController {
            // prepare stuff for Destination B
        }   
    }
}

Note: I realize a switch can be used, but that's not the point here.

注意:我知道可以使用开关,但这不是重点。

1 个解决方案

#1


1  

Relying on the identifier has the benefit that if your source/destination view controller got changed to another class, you can catch it more easily because it will fall into the right identifier bucket but fail the downcast. Strictly speaking, the code path is not the same. With the more succinct style, the failed case won't be caught until after all downcasts have been performed.

依赖标识符的好处是,如果您的源/目标视图控制器被更改为另一个类,您可以更容易地捕获它,因为它将落入正确的标识符桶中,但失败的向下投射。严格地说,代码路径并不相同。使用更简洁的风格,在执行所有的下行数据之后,失败的案例才会被发现。

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    if segue.identifier == "destinationA" {
        if let destination = segue.destinationViewController as? DestinationAController {
            // prepare stuff for Destination A
        }
        else {
           print("Something is wrong with the controller for destination A!")
        }
    } else if segue.identifier == "destinationB" {
        if let destination = segue.destinationViewController as? DestinationBController {
            // prepare stuff for Destination B
        }   
    }
}

vs.

vs。

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    if let destination = segue.destinationViewController as? DestinationAController {
        // prepare stuff for Destination A
    } else if let destination = segue.destinationViewController as? DestinationBController {
        // prepare stuff for Destination B
    }
    else {
      print("Something is wrong with the controller!")
    }
}

Another benefit is that you can do some other logic after the identifier test and before performing the downcast.

另一个好处是,您可以在标识符测试之后和执行下播之前执行一些其他逻辑。

It's also quicker to read the code using identifier in terms of intent - not only is it shorter, identifier being a Swift string can be made quite descriptive.

使用标识符阅读代码的目的也更快——不仅更短,标识符作为Swift字符串也可以被描述得更有描述性。

#1


1  

Relying on the identifier has the benefit that if your source/destination view controller got changed to another class, you can catch it more easily because it will fall into the right identifier bucket but fail the downcast. Strictly speaking, the code path is not the same. With the more succinct style, the failed case won't be caught until after all downcasts have been performed.

依赖标识符的好处是,如果您的源/目标视图控制器被更改为另一个类,您可以更容易地捕获它,因为它将落入正确的标识符桶中,但失败的向下投射。严格地说,代码路径并不相同。使用更简洁的风格,在执行所有的下行数据之后,失败的案例才会被发现。

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    if segue.identifier == "destinationA" {
        if let destination = segue.destinationViewController as? DestinationAController {
            // prepare stuff for Destination A
        }
        else {
           print("Something is wrong with the controller for destination A!")
        }
    } else if segue.identifier == "destinationB" {
        if let destination = segue.destinationViewController as? DestinationBController {
            // prepare stuff for Destination B
        }   
    }
}

vs.

vs。

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    if let destination = segue.destinationViewController as? DestinationAController {
        // prepare stuff for Destination A
    } else if let destination = segue.destinationViewController as? DestinationBController {
        // prepare stuff for Destination B
    }
    else {
      print("Something is wrong with the controller!")
    }
}

Another benefit is that you can do some other logic after the identifier test and before performing the downcast.

另一个好处是,您可以在标识符测试之后和执行下播之前执行一些其他逻辑。

It's also quicker to read the code using identifier in terms of intent - not only is it shorter, identifier being a Swift string can be made quite descriptive.

使用标识符阅读代码的目的也更快——不仅更短,标识符作为Swift字符串也可以被描述得更有描述性。