惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

P
Privacy & Cybersecurity Law Blog
人人都是产品经理
人人都是产品经理
The Cloudflare Blog
B
Blog RSS Feed
罗磊的独立博客
V
V2EX
V
Visual Studio Blog
博客园 - 叶小钗
W
WeLiveSecurity
小众软件
小众软件
K
Kaspersky official blog
美团技术团队
雷峰网
雷峰网
阮一峰的网络日志
阮一峰的网络日志
Martin Fowler
Martin Fowler
Recorded Future
Recorded Future
Project Zero
Project Zero
Hugging Face - Blog
Hugging Face - Blog
Engineering at Meta
Engineering at Meta
Security Latest
Security Latest
Microsoft Azure Blog
Microsoft Azure Blog
V
Vulnerabilities – Threatpost
月光博客
月光博客
博客园 - 三生石上(FineUI控件)
Help Net Security
Help Net Security
博客园 - Franky
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
F
Fortinet All Blogs
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Forbes - Security
Forbes - Security
M
MIT News - Artificial intelligence
H
Hacker News: Front Page
大猫的无限游戏
大猫的无限游戏
Vercel News
Vercel News
Spread Privacy
Spread Privacy
The Register - Security
The Register - Security
H
Hackread – Cybersecurity News, Data Breaches, AI and More
量子位
Google Online Security Blog
Google Online Security Blog
PCI Perspectives
PCI Perspectives
The Last Watchdog
The Last Watchdog
AI
AI
N
News | PayPal Newsroom
D
DataBreaches.Net
Cloudbric
Cloudbric
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
博客园 - 司徒正美
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
T
Tailwind CSS Blog

壹拾肆

2024 年做过的一些梦 2023 年做过的一些梦 2023 年终总结丨随时开始奔跑的心气 2022 年终总结丨惠存这一年 翻译:Why use dependency injection 是时候维护一个属于自己的开源库了 iOS 端豆瓣开源许可提到的库 推荐几个播客节目 iOS 自动化打包上传 AppleStore、fir.im,并发邮件通知测试人员 业余剪辑自我修养 Swift - 权限请求封装 iOS - HMAC 加密算法和一个 MD5 加密的问题 iOS - 一些蓝牙问题的解决 Swift - 顶部弹出框封装 被光放弃的人 OC - 多代理的实现 我的 AIO-notion 工作流搭建 解决使用 GitPage 重定向多次问题 《文学回忆录》读书笔记
Swift - ?和!的学习
Kaaaaai · 2020-04-24 · via 壹拾肆

  最近在优化一个项目的过程,过程中发现之前开发时由于刚接触 Swift 的原因,在 Swift 中的类里使用了很多 OC 的写法,比如字典数组对象会习惯性用 NSDictionaryNSArray来初始化,而不是用 [KeyType: ValueType]() 或是 [SomeType]() 这种类型来实例化变量。虽然在使用上没有什么问题,但看起来多少有点。。。不优雅。
  当我把大部分类型都修改成 Swift 中的写法后(部分未修改是因为使用 String 类型来给文本做截取和富文本定义,实在不如 NSString 顺手,这种不顺手让我不由想起 Stack Overflow 上看到的一个评论:I thougt i already getting along well with Swift.)发现,原来一些变量是否为空的判断中,使用 Swift 里的 optional 类型会方便很多。
  比如解析一个 json 数据,如果层级多而且里面每个元素都是不确定的,那么可能就需要每个层级都判一次空。而如果使用 ? 来设置当前对象为可选值,只需要在最后一层实际使用到对象值时,判一次空就 OK 了。
  对于 ? 和 ! 的区别和总结,网上有很多文章,在这里就不重复造轮子了。下面就对这个 optional 的自己两个疑问做个记录。   

? 和 ! 是表示两种不同的类型吗,一种是可以为空,一种不可以为空?

  刚开始使用的时候没做深入了解,以为 optional 中的 ? 和 ! 和 let 声明不可变变量,var 声明可变变量。? 和 ! 是一组彼此相对只是含义不同的两个符号。但深入了解了一下,发现并不是这样,引用两段官方的文档:

You use the Optional type whenever you use optional values, even if you never type the word Optional. Swift’s type system usually shows the wrapped type’s name with a trailing question mark (?) instead of showing the full type name. For example, if a variable has the type Int?, that’s just another way of writing Optional. The shortened form is preferred for ease of reading and writing code.

The types of shortForm and longForm in the following code sample are the same:

1
2
let shortForm: Int? = Int("42")
let longForm: Optional<Int> = Int("42")

  这里的意思是说当你使用 Optional 类型时的值,即使在初始化时没有用“Optional”这个单词指定类型,在 Swift 中也可用 ? 代替。即 Int? 等于 Optional<Int>。那按照之前我的理解,是否 ! 也是某个 Not Optional 单词的代替?后面官方文档就有提到了:

When you’re certain that an instance of Optional contains a value, you can unconditionally unwrap the value by using the forced unwrap operator (postfix !). For example, the result of the failable Int initializer is unconditionally unwrapped in the example below.

  意思是说 ! 是代表一种 Unconditional Unwrapping 的运算符,而并不是作为一种类型的表达。   

关于 Unconditional Unwrapping

  Unconditional Unwrapping 怎么理解,直译的话叫无条件展开,专业术语叫强制拆包。为什么使用 Optional 类型会需要强制拆包,如果使用 ! 运算符意味着强制拆包,那不使用 ! 时,Optional 是否还会做拆包的处理呢?
  仍然回到官方文档,有这句:

The Optional type is an enumeration with two cases. Optional.none is equivalent to the nil literal.

  也就是说 Optional 是一个默认带有 Optional.none 枚举类型的包装。所以使用时我们必须按官方说的:

You must unwrap the value of an Optional instance before you can use it in many contexts.

其他

  基于以上的学习和理解,我们可以来解读以下一些写法:

初始化
1
2
3
4
let value:NSString = nil 
let value:NSString!
let value:NSString? = nil
let value:NSString?
转换类型
1
2
3
4
5
6
7
8
9
10
let array:NSArray = NSMutableArray.init(object: "111")



print(array as! NSMutableArray)




print(array as? NSMutableArray)
方法定义
1
2
3
4
5
6
7
8

func buttonClick(sender: UIButton?){

}

func buttonClick(sender: UIButton){

}
1
2
3
4
5
let fruitDic: [String: String] = ["apple":"red","banana":"yellow"]
let apple: String! = fruitDic["apple"]!
let banana: String? = fruitDic["apple"]
let blueberry: String! = fruitDic["blueberry"] ?? ""
let orange: String? = fruitDic["orange"]