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. iOS开发中常见bug!(内附解答方法)

    序言 你是否曾经修复了一个 bug ,随后又发现了一个跟刚修复 bug 有关的 bug ,又或是修复 bug 的方式引起了另一个 bug ? 然而这些问题是绝佳的学习机会.所以我们怎样尽可能多地从修复 ...

  2. Android Foreground Service (前台服务)

    一.如何保活后台服务 在Android Services (后台服务) 里面,我们了解了Android四大组件之一的Service,知道如何使用后台服务进行来完成一些特定的任务.但是后台服务在系统内存 ...

  3. C# Redis实战(五)

    五.删除数据 在C# Redis实战(四)中讲述了如何在Redis中写入key-value型数据,本篇将讲述如何删除Redis中数据. 1.void Delete(T entity);删除函数的运用 ...

  4. WordPress添加个性化的博客宠物的方法

    在很多的网站上都看见过这种效果,于是自己也想试试.看见我网站上的小宠物了吗,就是这种效果. 不多说,方法如下: 工具: 下载地址:http://yunpan.cn/cFUmZB8WWthty 访问密码 ...

  5. Unity3D 打包Standalone(exe文件) Shader丢失

    Shader丢失算是老生常谈了 从刚开始接触Unity时,从别的地方拿过来模型导入 就认识了一个标志性的颜色 就是粉色,或者是紫色 当在Unity中遇到这种颜色 不用怀疑 绝对是Shader或者材质丢 ...

  6. 温故而知新--hashtable

    哈希在实际使用中主要是当作私有内存,对数据进行插入和查找,哈希数据元素越多,操作的时候消耗的性能就越到,最明显的是当数据元素达到哈希的容量大小时,插入数据冲突概率会变大,并慢慢的退化为数组. 本例子中 ...

  7. Codeforces Round #467 (Div. 1). C - Lock Puzzle

    #include <algorithm> #include <cstdio> #include <cstring> #include <iostream> ...

  8. Java基础_Java概述

    Java_概述 特点: 平台的移植性 开源 面向对象 多线程 安全性 工作方式: 先编译再解释执行. 先通过Javac命令将Java源代码编译成字节码文件(bytecode,类文件,.class,中间 ...

  9. WinSock 异步I/O模型-1

    异步选择(WSAAsyncSelect):异步选择基本定义 异步选择(WSAAsyncSelect)模型是一个有用的异步 I/O 模型.利用这个模型,应用程序可在一个套接字上,接收以 Windows ...

  10. 学习java第一章

    本人是一名5年工作的人了,出来社会也比较早,工作经验比起刚刚出社会的大学生要和很多了,知道社会的现实与无奈,我为什么选择想学java昵,肯定受到了朋友的影响的,接下来就讲讲我学习java的过程. 1. ...