gpt4 book ai didi

Swift中非可选的可选值类型处理方法详解

转载 作者:qq735679552 更新时间:2022-09-28 22:32:09 27 4
gpt4 key购买 nike

CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.

这篇CFSDN的博客文章Swift中非可选的可选值类型处理方法详解由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.

前言 。

在我们使用objective-c表示字符串信息的时候,可以用下面方法书写.

?
1
2
NSString *str = @ "秋恨雪" ;
str = nil;

因为objective-c是弱类型语言,所以这里的str既可以是具体的字符串也可以是nil。但到了Swift中就不可以了,因为Swift是类型安全的语言,一个String类型的变量不可能既能是具体的字符串,又可以为nil(更严格的说String类型的内容只能是字符串)。所以,在Swift中有了可选类型的概念。(其实这一概念也是“借鉴”于其他编程语言,比如C#,只不过在C#中称之为可空类型).

大家在初看Optionals的感觉很陌生,在我第一眼看到它的时候,我就在想...这是什么鬼...但是仔细想想的话,可选值Optionals类型的引入,为我们也带了便利. 。

可选值(optionals)无可争议的是 swift 语言中最重要的特性之一,也是和其他语言,例如 Objective-C 的最大区别。通过强制处理那些有可能出现 nil 的地方,我们就能写出更有预测性的以及更健壮的代码.

然而,有些时候可选值可能会致你于尴尬的境地,尤其是你作为开发者了解(甚至是有些猜测的成分在),有的特定变量始终是非空(non-nil)的,即使它是一个可选类型。例如,我们在一个视图控制器中处理视图的时候:

?
1
2
3
4
5
6
7
8
9
10
11
class TableViewController: UIViewController {
  var tableView: UITableView?
  override func viewDidLoad() {
   super.viewDidLoad()
   tableView = UITableView(frame: view.bounds)
   view.addSubview(tableView!)
  }
  func viewModelDidUpdate(_ viewModel: ViewModel) {
   tableView?.reloadData()
  }
}

这也是对于很多 Swift 程序员争论比较激烈的地方,程度不亚于讨论 tabs 和 spaces 的用法。有的人会说:

既然它是一个可选值,你就应该时刻使用 if let 或者 guard let 的方式进行解包.

然而另外一些人则采用完全相反,说:

既然你知道这个变量在使用的时候不会为 nil,使用 ! 强制解包多好。崩溃也要比让你的程序处于一个未知状态要好吧.

本质上来讲,我们这里讨论的是要不要采用防御性编程(defensive programming)的问题。我们是试图让程序从一个未知状态恢复还是简单的放弃,然后让它崩溃掉?

如果非得让我对这个问题给出一个答案的话,我更倾向于后者。未知状态真的很难追踪 bug,会导致执行很多不想执行的逻辑,采用防御性编程就会使得你的代码很难追踪,出现问题很难追踪.

但是,我不太喜欢给出一个二选一的答案。相反,我们可以寻找一些技术手法,用更精妙的方式的解决上面提到的问题.

它真的可选的吗?

那些可选类型的,但是被代码逻辑真实需要的变量和属性,实际上是架构瑕疵的一个体现。如果在某些地方确实需要它,但是它又不在,就会使得你的代码逻辑处于未知状态,那么它就不应该是可选类型的.

当然,在某些特定场景下,可选值确实很难避免(尤其是和特定的系统 API 交互的时候),那对于大部分这种情况,我们有一些技术来处理从而避免可选值.

lazy 要比非可选的可选值更好 。

某些属性的值需要在其父类创建之后再生成(比如视图控制器中的那些视图,应该在 loadView()或者 viewDidLoad()方法中被创建),对于这种属性要避免其可选类型的方法就是使用 lazy 属性。一个lazy属性是可以是非可选类型的,同时也不在其父类的初始化方法里被需要,它会在其第一次被获取的时候创建出来.

让我们改一下上面的代码,使用 lazy 来改造 tableView 属性:

?
1
2
3
4
5
6
7
8
9
10
11
class TableViewController: UIViewController {
  lazy var tableView = UITableView()
  override func viewDidLoad() {
   super.viewDidLoad()
   tableView.frame = view.bounds
   view.addSubview(tableView)
  }
  func viewModelDidUpdate(_ viewModel: ViewModel) {
   tableView.reloadData()
  }
}

这样,没有可选值了,也不会有未知状态咯 。

最后此篇关于Swift中非可选的可选值类型处理方法详解的文章就讲到这里了,如果你想了解更多关于Swift中非可选的可选值类型处理方法详解的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com