Swift 3:如何在没有多个if let语句的情况下为不同选项类型的变量赋值?
Swift 3: How to assign variable of different option types without multiple if let statements?
首先,如果标题含糊不清,我深表歉意。请随意更改它以符合问题描述。
我会尽力描述我的问题,但首先是一段代码:
if let vc = currentVC as? FirstViewController
{
vc.doSameMethod()
}
else if let vc = currentVC as? SecondViewController
{
vc.doSameMethod()
}
else if let vc = currentVC as? ThirdViewController
{
vc.doSameMethod()
}
基本上,我使用 if let
语句来检查可选的 nil,然后解包并分配它。
我在所有 3 个 ViewController 中都有 doSameMethod()
函数,它们使用相同的函数名称执行几乎相同的任务。
我的问题是,我怎样才能避免重复代码:
if let vc = (currentVC as? FirstViewController || current as? SecondViewController || currentVC as? ThirdViewController)
{
vc.doSameMethod()
}
显然,上面的代码无法编译,但我想知道是否有更简单、更清晰的方法来通过检查多种类型来解包可选?
谢谢!
你可以用一个协议来做。用所有 3 个视图控制器之间的通用方法定义一个协议并使它们符合它:
protocol MyViewControllerProtocol {
func doSameMethod()
}
class FirstViewController: UIController, MyViewControllerProtocol {
// your code
}
class SecondViewController: UIController, MyViewControllerProtocol {
// your code
}
class ThirdViewController: UIController, MyViewControllerProtocol {
// your code
}
用法:
if let vc = currentVC as? MyViewControllerProtocol {
vc.doSameMethod()
}
如果您有多个视图控制器,它们都实现了相同的方法,那么协议是一个不错的选择,如@CodeDifferent 的回答中所述。
如果每个视图控制器都有不同的界面,并且您需要根据传递给您的视图控制器做不同的事情,您可以使用带有 case let newConstant as <type>:
[=18= 的 switch 语句的变体]
这是在 prepareForSegue 方法中使用的示例代码片段,您可能在其中处理到视图控制器的几个不同 classes 之一的 segue:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
switch segue.destinationViewController {
case let fooViewController as FooViewController:
fooViewController.delegate = self
case let barViewController as BarViewController:
barViewController.data = data
default:
break
}
}
在您的情况下,它会显示为
switch currentVC {
case let firstVC as FirstViewController:
//code for FirstViewController
case let secondVC as SecondViewController:
//code for SecondViewController
case let thirdVC as ThirdViewController:
//code for ThirdViewController
}
如果 currentVC
是指定的 class 的对象,则选择一个案例。此外,在该 case 语句中,有一个定义为正确类型的局部常量,就像在 if let 中一样。
编辑 - 从 "Matching based on class - great for prepareForSegue" 复制的完整示例,来自现已失效的 Whosebug 文档:
你也可以根据你打开的东西的 class 做一个 switch 语句切换。
prepareForSegue
中的一个有用示例。我曾经根据 segue 标识符进行切换,但这很脆弱。如果您稍后更改故事板并重命名 segue 标识符,它会破坏您的代码。或者,如果您对同一视图控制器 class(但故事板场景不同)的多个实例使用 segue,则无法使用 segue 标识符来确定目标的 class。
Swift switch 语句来拯救。
使用Swift case let var as Class
语法,像这样:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
switch segue.destinationViewController {
case let fooViewController as FooViewController:
fooViewController.delegate = self
case let barViewController as BarViewController:
barViewController.data = data
default:
break
}
}
在 Swift 3 中语法略有变化:
override func prepare(for segue: UIStoryboardSegue, sender: AnyObject?) {
switch segue.destinationViewController {
case let fooViewController as FooViewController:
fooViewController.delegate = self
case let barViewController as BarViewController:
barViewController.data = data
default:
break
}
}
首先,如果标题含糊不清,我深表歉意。请随意更改它以符合问题描述。
我会尽力描述我的问题,但首先是一段代码:
if let vc = currentVC as? FirstViewController
{
vc.doSameMethod()
}
else if let vc = currentVC as? SecondViewController
{
vc.doSameMethod()
}
else if let vc = currentVC as? ThirdViewController
{
vc.doSameMethod()
}
基本上,我使用 if let
语句来检查可选的 nil,然后解包并分配它。
我在所有 3 个 ViewController 中都有 doSameMethod()
函数,它们使用相同的函数名称执行几乎相同的任务。
我的问题是,我怎样才能避免重复代码:
if let vc = (currentVC as? FirstViewController || current as? SecondViewController || currentVC as? ThirdViewController)
{
vc.doSameMethod()
}
显然,上面的代码无法编译,但我想知道是否有更简单、更清晰的方法来通过检查多种类型来解包可选?
谢谢!
你可以用一个协议来做。用所有 3 个视图控制器之间的通用方法定义一个协议并使它们符合它:
protocol MyViewControllerProtocol {
func doSameMethod()
}
class FirstViewController: UIController, MyViewControllerProtocol {
// your code
}
class SecondViewController: UIController, MyViewControllerProtocol {
// your code
}
class ThirdViewController: UIController, MyViewControllerProtocol {
// your code
}
用法:
if let vc = currentVC as? MyViewControllerProtocol {
vc.doSameMethod()
}
如果您有多个视图控制器,它们都实现了相同的方法,那么协议是一个不错的选择,如@CodeDifferent 的回答中所述。
如果每个视图控制器都有不同的界面,并且您需要根据传递给您的视图控制器做不同的事情,您可以使用带有 case let newConstant as <type>:
[=18= 的 switch 语句的变体]
这是在 prepareForSegue 方法中使用的示例代码片段,您可能在其中处理到视图控制器的几个不同 classes 之一的 segue:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
switch segue.destinationViewController {
case let fooViewController as FooViewController:
fooViewController.delegate = self
case let barViewController as BarViewController:
barViewController.data = data
default:
break
}
}
在您的情况下,它会显示为
switch currentVC {
case let firstVC as FirstViewController:
//code for FirstViewController
case let secondVC as SecondViewController:
//code for SecondViewController
case let thirdVC as ThirdViewController:
//code for ThirdViewController
}
如果 currentVC
是指定的 class 的对象,则选择一个案例。此外,在该 case 语句中,有一个定义为正确类型的局部常量,就像在 if let 中一样。
编辑 - 从 "Matching based on class - great for prepareForSegue" 复制的完整示例,来自现已失效的 Whosebug 文档:
你也可以根据你打开的东西的 class 做一个 switch 语句切换。
prepareForSegue
中的一个有用示例。我曾经根据 segue 标识符进行切换,但这很脆弱。如果您稍后更改故事板并重命名 segue 标识符,它会破坏您的代码。或者,如果您对同一视图控制器 class(但故事板场景不同)的多个实例使用 segue,则无法使用 segue 标识符来确定目标的 class。
Swift switch 语句来拯救。
使用Swift case let var as Class
语法,像这样:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
switch segue.destinationViewController {
case let fooViewController as FooViewController:
fooViewController.delegate = self
case let barViewController as BarViewController:
barViewController.data = data
default:
break
}
}
在 Swift 3 中语法略有变化:
override func prepare(for segue: UIStoryboardSegue, sender: AnyObject?) {
switch segue.destinationViewController {
case let fooViewController as FooViewController:
fooViewController.delegate = self
case let barViewController as BarViewController:
barViewController.data = data
default:
break
}
}