码迷,mamicode.com
首页 > 编程语言 > 详细

swift中的optional

时间:2017-01-21 17:10:48      阅读:249      评论:0      收藏:0      [点我收藏+]

标签:err   编译器   取值   word   object-c   过程   block   reflect   实现   

optional一些理解和总结:

Optional作为一种类型,既可以存储一个值,也可以为空(也就是swift里的nil);

其实为一个枚举类型,包含nil或者一个值,如下;

enum Optional<T>: _Reflectable, NilLiteralConvertible {
    case None
    case Some(T)
    //...
}

它只有两种状态,包含一个值或者为空;
optional有效解决了值为空的清空;
我们可以通过判断一个对象是否为空了做出相应解决,通过if let a = b(optional)的方式实现一个解包过程,并在条件中使用a,而不再解包;
针对anyobject,由于直到运行时才知道AnyObject的对象类型,所以有可能在不经意间写出不安全代码,
如:let timeSinceNow = myObject.timeIntervalSinceNow;
当一个anyobject类型的对象去调用某个方法,而该对象不存在此方法(optional对象调用方法会隐式展开),如下;
let timeSinceNow = myObject.timeIntervalSinceNow?();  ----此时当方法不存在时,timeSinceNow被推测为对应类型,并被赋予一个nil值;
接着可以使用if let方式判断来使用该对象;这个就避免了anyobject运行时才确定类型而报错的问题

对于隐式解包:访问时,编译器会自动帮我们完成在变量后插入!的行为
当我在项目中明确确定该属性一定会被初始化;且在使用范围内不会为空时,在声明属性时就可以使用!表示隐式解包;
这类属性主要这对UI控件,通常情况,控件都不会为空,这样避免了繁杂的解包过程以及判断过程;
隐式解包的来源摘自百度:
  王巍在他的Swift Tip解释了一下:

这一切都是历史的锅。因为Object-C中Cocoa的所有类型变量都是可以指向nil的,有一部分Cocoa的API中在参数或者返回时即使被声明为具体的类型,但是还是可能在某些特定的情况下是nil, 而同时也有另一部分API永远不会接受或者返回nil。在Objective-C时,这两种情况并没有加以区别,因为在OC中向nil发送消息是允许的,结果就是什么都不会发生,而在Cocoa API从OC转为Swift的module声明的自动化工具里,是无法判定是否存在nil的可能的,因此也无法决定哪些类型应该是实际的类型,而哪些类型应该声明为Optional。

在这种自动化转换中,最简单粗暴的应对方式是全部转为 Optional,然后让使用者通过 Optional Binding 来判断并使用。虽然这是最安全的方式,但对使用者来说是一件非常麻烦的事情,我猜不会有人喜欢每次用个 API 就在 Optional 和普通类型之间转来转去。这时候,隐式解包的 Optional 就作为一个妥协方案出现了。使用隐式解包 Optional 的最大好处是对于那些我们能确认的 API 来说,我们可直接进行属性访问和方法调用,会很方便。但是需要牢记在心的是,隐式解包不意味着 “这个变量不会是 nil,你可以放心使用” 这种暗示,只能说 Swift 通过这个特性给了我们一种简便但是危险的使用方式罢了。


当然隐式解包也会有问题,尝试访问一个为空的隐式解包Optional,就会遇到一个runtime error;
这种问题在自己项目中最常见的就是在异步线程(主要为网络请求)中主动去调用控件;当对象销毁而线程延迟执行时就会崩溃;在调用对象前主动判断对象为空否。

针对optional的属性和方法,可以通过链(Optional Chaining)来实现安全访问,如同anyobject使用一样;
let b: Int?
if let a = b?.sum(){a的使用};-----摆脱很多不必要的判断和取值,从而精简代码。

swift中可以使用??来设置一个默认值;
同上:if let a = b?sum() ?? 1 -----如果b为空了,给a赋值1;
设置默认值的方法在项目中很方便;
当你封装一个方法,而针对不同的调用者是??可有效解决调用者身份判断问题。
列:
  func addNum(a: Int, b: Int, c: Int = nil) -> Int{if c == nil {return a + b} else (return a + b - c)}
而你在调用该方法时,系统会提供自动两个func
;--------次方法在代码高度封装以及一些特殊判断中非常有效;

关于oc方法调用:oc中对象应用可以为NULL,而swift中必须为非空;所以当在swift中使用oc对象时必须保证其位非空;

以次文纪念我死在开发道路上的脑细胞。

swift中的optional

标签:err   编译器   取值   word   object-c   过程   block   reflect   实现   

原文地址:http://www.cnblogs.com/hazhede/p/6337239.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!