Swift语言使用var定义变量,但和别的语言不同,Swift里不会自动给变量赋初始值,

也就是说变量不会有默认值,所以要求使用变量之前必须要对其初始化

。如果在使用变量之前不进行初始化就会报错:

  1. var stringValue : String
  2. //error: variable 'stringValue' used before being initialized
  3. //let hashValue = stringValue.hashValue
  4. //                            ^
  5. let hashValue = stringValue.hashValue

出错的原因就是在使用stringValue这个变量之前,没有初始化这个变量,也就是这个变量根本就没有得到内存,

这时就会出错。

那么我们可以使用optional类型,后面跟一个?就是了。

  1. // 这就是optional, strValue自动得到默认值:nil
  2. // 这个nil跟Objective-C中的nil不同,不是指针,而是表示值不存在。
  3. var strValue: String?
  4. // 判断optional是否有值
  5. if strValue {
  6. // do what you need to do here
  7. }

文档中有提到说,在使用Optional值的时候需要在具体的操作,比如调用方法、属性、下标索引等前面需要加上一个?,如果是nil值(不存在值),也就是Optional.None,会跳过后面的操作不执行,如果有值,就是Optional.Some可能就会拆包(unwrap),然后对拆包后的值执行后面的操作,来保证执行这个操作的安全性,比如Optional
binding:

  1. // optional binding
  2. // 如果strValue == nil, 那么结果就是nil,不会调用String的hasValue
  3. // 如果strValue != nil, 就返回strValue对应的hashValue值并赋值给常量hashValue
  4. if let hashValue = strValue?.hashValue {
  5. // do something if neccessary
  6. }

在写协议(protocol)时,对于可选代理方法,也需要在调用时在函数名后跟着?,如:

  1. // @objc 是用于处理Swift与OC之间的转换的,由于@optional是OC中的关键字,
  2. // 所以在protocol之前需要添加上@objc。
  3. @objc protocol HttpRequestDelegate {
  4. // @optional 说明这个代理方法是可选方法,
  5. // 那么在调用的时候,需要这样调用:delegate?.requestFinished?(self, downloadData)
  6. // 其中delegate?是因为delegate也是optional的
  7. @optional func requestFinished(request: HttpRequest!, downloadData: NSMutableData!)
  8. // other funcs ...
  9. }
  10. var delegate: HttpRequestDelegate?
  11. var downloadData = NSMutableData()
  12. delegate.requestFinished(self, downloadData)

当然我们也可以使用!来强制拆包,这是我们在保证有值的情况下才会这么用:

  1. var strValue: String?
  2. strValue = "1234"
  3. let integer = strValue!.toInt()
  4. // 更安全的写法是
  5. if strValue {
  6. let integer = strValue!.toInt()

隐式强拆包类型:

使用!来声明变量,会成为隐式强拆包可选类型,这表示这个类型永远不会出现nil的情况,但一旦出来,

在调用时就会崩溃。

  1. // Implicitly Unwrapped Optionals
  2. // 使用这种方式声明的话,在调用时不需要使用?或!来说明。
  3. var myLabel: UILabel!
  4. myLabel = UILabel(frame: CGRectMake(10, 100, 300, 10))
  5. myLabel.text = "label"

总结:

通常在什么情况下才会使用optional类型呢?

(1)当我们需要声明这样一个变量,变量在设计初始化函数中没有进行初始化时,就需要声明这个变量为optional类型。因为变量在使用前必须先

声明,并且在设计初始化函数中进行初始化。比如我们在viewDidLoad函数中才进行初始化的控件(类成员),就需要声明为optional且必须是var声明,

因为let声明的常量只能是在初始化函数中进行初始化。

(2)当我们不知道是否会有值的时候,这个变量可以声明为optional,比如代理,我们并没有要求必须传代理过来,那么就需要声明为optional。

(3)作为函数参数时,如果这个参数可以没有值,那么就使用optional类型,比如传代理的时候,通常就是可选的,可以设置为nil

......暂时只想到这些,任何人都可以继续往下补充!

【iOS】Swift ?和 !(详解)的更多相关文章

  1. iOS开发-Runtime详解

    iOS开发-Runtime详解 简介 Runtime 又叫运行时,是一套底层的 C 语言 API,其为 iOS 内部的核心之一,我们平时编写的 OC 代码,底层都是基于它来实现的.比如: [recei ...

  2. 转载]IOS LBS功能详解[0](获取经纬度)[1](获取当前地理位置文本 )

    原文地址:IOS LBS功能详解[0](获取经纬度)[1](获取当前地理位置文本作者:佐佐木小次郎 因为最近项目上要用有关LBS的功能.于是我便做一下预研. 一般说来LBS功能一般分为两块:一块是地理 ...

  3. iOS中-Qutarz2D详解及使用

    在iOS中Qutarz2D 详解及使用 (一)初识 介绍 Quartz 2D是二维绘图引擎. 能完成的工作有: 绘制图形 : 线条\三角形\矩形\圆\弧等 绘制文字 绘制\生成图片(图像) 读取\生成 ...

  4. iOS 2D绘图详解(Quartz 2D)之路径(点,直线,虚线,曲线,圆弧,椭圆,矩形)

    前言:一个路径可以包含由一个或者多个shape以及子路径subpath,quartz提供了很多方便的shape可以直接调用.例如:point,line,Arc(圆弧),Curves(曲线),Ellip ...

  5. iOS开发——Block详解

    iOS开发--Block详解 1. Block是什么 代码块 匿名函数 闭包--能够读取其他函数内部变量的函数 函数变量 实现基于指针和函数指针 实现回调的机制 Block是一个非常有特色的语法,它可 ...

  6. iOS开发:详解Objective-C runTime

    Objective-C总Runtime的那点事儿(一)消息机制 最近在找工作,Objective-C中的Runtime是经常被问到的一个问题,几乎是面试大公司必问的一个问题.当然还有一些其他问题也几乎 ...

  7. iOS应用开发详解

    <iOS应用开发详解> 基本信息 作者: 郭宏志    出版社:电子工业出版社 ISBN:9787121207075 上架时间:2013-6-28 出版日期:2013 年7月 开本:16开 ...

  8. 了解iOS消息推送一文就够:史上最全iOS Push技术详解

    本文作者:陈裕发, 腾讯系统测试工程师,由腾讯WeTest整理发表. 1.引言 开发iOS系统中的Push推送,通常有以下3种情况: 1)在线Push:比如QQ.微信等IM界面处于前台时,聊天消息和指 ...

  9. iOS开发者证书-详解

    iOS开发者证书-详解/生成/使用 本文假设你已经有一些基本的Xcode开发经验, 并注册了iOS开发者账号. 相关基础 加密算法 现代密码学中, 主要有两种加密算法: 对称密钥加密 和 公开密钥加密 ...

  10. iOS NSTimer使用详解 开启、关闭、移除

    定时器定时器详解ios定时器关闭定时器NSTimer 一,要使用一个定时器首先要定义一个定时器: @property (strong, nonatomic) NSTimer *myTimer;//定时 ...

随机推荐

  1. 你该怎么选Offer

    原文出处:http://www.360doc.com/content/15/1223/07/1209677_522436084.shtml 记录目的:自勉.分享 摘要 一段时间无数公司.无数投资人蜂拥 ...

  2. hihocoder #1456 : Rikka with Lattice(杜教筛)

    hihocoder #1456 : Rikka with Lattice(杜教筛) 题意 : 给你一个\(n*m\)方格图,统计上面有多少个格点三角形,除了三个顶点,不覆盖其他的格点(包括边和内部). ...

  3. Luogu Dynamic Ranking (带修改的主席树)

    题目大意: 网址:https://www.luogu.org/problemnew/show/2617 给定一个序列a[1].a[2].....a[N],完成M个操作,操作有两种: [1]Q i j ...

  4. 1.Docker是什么?

    Docker官网是这样解释的: Docker is the company driving the container movement and the only container platform ...

  5. sdk安装

    转自:https://www.cnblogs.com/smyhvae/p/4390905.html   安装sdk:(包解压到哪里就是sdk的安装目录 P.S.安装目录不能有空格,要是之前有空格换了目 ...

  6. java ssm框架实现分页功能 (oracle)

    java web 实现分页功能 使用框架:ssm 数据库:oracle 话说 oracle 的分页查询比 mysql 复杂多了,在这里简单谈一下: 查询 前十条数据: SELECT * FROM( S ...

  7. Shiro入门这篇就够了【Shiro的基础知识、回顾URL拦截】

    前言 本文主要讲解的知识点有以下: 权限管理的基础知识 模型 粗粒度和细粒度的概念 回顾URL拦截的实现 Shiro的介绍与简单入门 一.Shiro基础知识 在学习Shiro这个框架之前,首先我们要先 ...

  8. PPT分享 | 以太坊钱包分析与介绍

    艾伯特AI人工智能(公众号:aibbtcom)按: (编者按:本文为姗姗来迟的Meetup系列推文.12月3日,林修平在亚太区以太坊社区培训与交流Meetup深圳站上跟我们分享了他对以太坊各种钱包模式 ...

  9. Spring Security 源码解析(一)AbstractAuthenticationProcessingFilter

    # 前言 最近在做 Spring OAuth2 登录,并在登录之后保存 Cookies.具体而言就是 Spring OAuth2 和 Spring Security 集成.Google一下竟然没有发现 ...

  10. Knowledge point

    静态网页的特点:以htm.html.sbtml.xml.js.css等为后缀扩展名. 1)程序在客户浏览器端解析,不需要读取数据库,性能和效率较高: 2)后端没有数据库支持,所以和用户的交互性差,功能 ...