《Swift编程教程Swift语言快速入门第八章.pdf》由会员分享,可在线阅读,更多相关《Swift编程教程Swift语言快速入门第八章.pdf(49页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、Swift 语言快速入门(内部资料) 版权所有 大学霸出品 Swift 语言快速入门(内部资料)大学霸 Swift 语言快速入门(内部资料) 版权所有 大学霸出品 Swift 语言快速入门(内部资料) 版权所有 大学霸出品 前 言 Swift 是苹果公司在 2014 年 WWDC 大会上推出的新的编程语言,用于取代原有的苹果官方语言Objective-C。Swift 主要用于编写 iOS 和 Mac OS 应用程序。在此编程语言推出以后,就有将近 37 万的开发者在苹果官网下载 Swift 手册进行学习。同时,Swift 中文版也由国内自发的翻译小组花费 9 天时间完成。通过Swift 中文版
2、,读者可以了解 Swift 的一些语法特性。但由于它只是对语法手册的翻译,存在以下缺陷:第一,它仅是一个语法词典,只是简单地、逐条地对语法进行解释。类似于学英语,靠一本英语词典学会英语,难度是相当的高。第二,它所具备的实例有限。地球人都知道,学习编程语言的最佳手段是通过实例代码学习。没有足够的实例,只靠零星的代码片段或语法就能理解 Swift,那是高手所为。基于以上不可忽略的事实,本书决定着眼于讲解 Swift 语言的入门,将苹果官方提供的 Swift 手册内容重新进行系统的划分,并针对每一个知识点配套相应实例,帮助读者可以快速学习和掌握 Swift 语言。1.学习所需的系统和软件学习所需的系
3、统和软件 Mac OS 10.9.4 以上的操作系统 安装 Xcode 6 2.学习建议学习建议 大家学习之前,可以致信到 ,获取相关的资料和软件。如果大家在学习过程遇到问题,也可以将问题发送到该邮箱。我们将尽力给大家解决。Swift 语言快速入门(内部资料) 版权所有 大学霸出品 目 录 第 1 章 编写第一个Swift程序.1 1.1 初识Swift.1 1.1.1 Swift的诞生.1 1.1.2 Swift的特点与不足.1 1.2 搭建开发环境.2 1.2.1 安装Xcode 6.2 1.2.2 安装组件.3 1.2.3 更新组件和文档.3 1.3 编写第一个程序.4 1.3.1 创建
4、项目.4 1.3.2 Xcode 6 界面介绍.7 1.3.3 编译和运行.9 1.3.4 编写代码.10 1.3.5 生成可执行文件.11 1.4 Swift代码分析.12 1.4.1 代码的构成.12 1.4.2 标识符.13 1.4.3 关键字.14 1.4.4 注释.14 1.4.5 文件构成.15 1.5 使用帮助文档.16 第 2 章 数据类型.17 2.1 常量变量.18 2.1.1 常量.18 2.1.2 变量.18 2.1.3 为声明的变量和常量指定数据类型.19 2.2 简单的数据类型.20 2.2.1 整数(Integer).20 2.2.2 整型.21 2.2.3 浮点
5、类型.21 2.2.4 字符类型/字符串类型.23 2.2.5 布尔类型.23 2.2.6 可选类型.24 2.3 字面值.25 2.3.1 整型字面值.25 2.3.2 浮点类型的字面值.25 2.3.3 字符型字面值.26 2.3.4 字符串字面值.26 Swift 语言快速入门(内部资料) 版权所有 大学霸出品 2 2.3.5 布尔类型的字面值.27 2.4 高级数据类型元组.27 2.5 类型别名.29 第 3 章 语句和表达式.30 3.1 语句.30 3.2 运算符与表达式.30 3.2.1 常用术语元.30 3.2.2 赋值运算符和表达式.31 3.2.3 算术运算符和表达式.3
6、1 3.2.4 取余运算符和表达式.33 3.2.5 自增自减运算符和表达式.34 3.2.6 一元减运算符.36 3.2.7 一元加运算符.36 3.2.8 位运算符.37 3.2.9 溢出运算符.43 3.2.10 比较运算符和表达式.46 3.2.11 三元条件运算符.47 3.2.12 逻辑运算符和表达式.47 3.2.13 范围运算符.49 3.2.14 复合赋值运算符和表达式.51 3.2.15 求字节运算符和表达式.51 3.2.16 强制解析.52 3.3 类型转换.53 3.3.1 整数的转换.53 3.3.2 整数和浮点数的转换.53 第 4 章 字符串.54 4.1 字符
7、串的初始化.54 4.1.1 字符串的种类.54 4.1.2 初始化空的字符串.55 4.1.3 使用字符串初始化字符串.55 4.1.4 计算字符个数.56 4.1.5 遍历字符.56 4.2 字符串组合.56 4.2.1 字符串与字符组合.57 4.2.2 字符串与字符串组合.57 4.3 字符串判断.58 4.3.1 判断字符串是否为空.59 4.3.2 判断字符串相等.59 4.3.3 判断前缀.60 4.3.4 判断后缀.60 4.4 大小写转换.61 Swift 语言快速入门(内部资料) 版权所有 大学霸出品 3 4.4.1 大写转换.61 4.4.2 小写转换.62 4.5 Un
8、icode编码.62 4.5.1 Unicode术语.62 4.5.2 Unicode字符串.63 4.5.3 UTF-8 编码.63 4.5.4 UTF-16 编码.63 4.5.5 UTF标量.64 第 5 章 集合类型.64 5.1 数组.64 5.1.1 数组字面量.65 5.1.2 数组的定义.65 5.1.3 数组的初始化.65 5.2 数组的操作.67 5.2.1 获取数组中元素的个数.67 5.2.2 判断数组是否为空.67 5.2.3 判断两个数组是否共用相同的元素.68 5.2.4 复制数组.69 5.2.5 在末尾添加一个元素.69 5.2.6 插入值.70 5.2.7
9、读取值.70 5.2.8 修改值.71 5.2.9 删除值.72 5.2.10 遍历数组.73 5.3 字典.74 5.3.1 字典字面量.74 5.3.2 字典的定义.75 5.3.3 字典的初始化.75 5.4 字典的操作.76 5.4.1 获取字典中的元素个数.76 5.4.2 读取键的值.76 5.4.3 添加元素.77 5.4.4 修改键关联的值.77 5.4.5 删除键.78 5.4.6 遍历.79 5.5 可变的集合类型.81 第 6 章 程序控制结构.81 6.1 顺序结构.81 6.1.1 程序的执行流程.81 6.1.2 代码调试.82 6.2 选择结构if语句.83 Sw
10、ift 语言快速入门(内部资料) 版权所有 大学霸出品 4 6.2.1 if语句.83 6.2.2 if.else语句.84 6.2.3 if.else if语句.86 6.3 选择结构switch语句.87 6.3.1 switch语句基本形式.88 6.3.2 规则 1:相同的常量或常量表达式.90 6.3.3 规则 2:可执行的语句不能为空.90 6.3.4 规则 3:多条件组合.90 6.3.5 规则 4:范围匹配.91 6.3.6 规则 5:使用元组.91 6.3.7 规则 6:数值绑定.92 6.3.8 规则 7:使用where关键字.93 6.4 循环结构for语句.94 6.4
11、.1 for.in循环.95 6.4.2 for-condition-increment条件循环.96 6.5 循环结构while语句.97 6.5.1 while循环.98 6.5.2 do while循环.99 6.6 跳转语句.100 6.6.1 continue语句.100 6.6.2 break语句.100 6.6.3 fallthrough语句.101 6.6.4 使用标签语句.102 第 7 章 函数和闭包.104 7.1 函数介绍.104 7.2 使用无参函数.105 7.2.1 无参函数的声明定义.105 7.2.2 无参函数的调用.106 7.2.3 空函数.107 7.3
12、 使用有参函数.107 7.3.1 有参函数的声明定义.107 7.3.2 有参函数的调用.108 7.3.3 参数的注意事项.108 7.4 函数参数的特殊情况.109 7.4.1 本地参数名.109 7.4.2 外部参数名.110 7.4.3 设定参数默认值.111 7.4.4 为外部参数设置默认值.112 7.4.5 可变参数.112 7.4.6 常量参数和变量参数.113 7.4.7 输入-输出参数.114 Swift 语言快速入门(内部资料) 版权所有 大学霸出品 5 7.5 函数的返回值.116 7.5.1 具有一个返回值的函数.116 7.5.2 具有多个返回值的函数.116 7
13、.5.3 无返回值.118 7.6 函数类型.118 7.6.1 使用函数类型.118 7.6.2 使用函数类型作为参数类型.119 7.6.3 使用函数类型作为返回值类型.120 7.7 标准函数.121 7.7.1 绝对值函数abs().121 7.7.2 最大值函数max()/最小值min().121 7.7.3 序列的最大值函数maxElement()/最小值函数minElement().123 7.7.4 判断序列是否包含指定元素函数contains().124 7.7.5 序列排序函数sort().124 7.7.6 序列倒序函数reverse().125 7.8 函数嵌套调用形式
14、.125 7.8.1 嵌套调用基本形式.126 7.8.2 递归调用.127 7.9 闭包.128 7.9.1 闭包表达式.128 7.9.2 使用闭包表达式的注意事项.131 7.9.3 Trailing闭包.132 7.9.4 捕获值.134 第 8 章 类.134 8.1 类与对象.135 8.1.1 类的组成.135 8.1.2 创建类.135 8.1.3 实例化对象.136 8.2 属性.136 8.2.1 存储属性.136 8.2.2 计算属性.141 8.2.3 类型属性.145 8.2.4 属性监视器.147 8.3 方法.150 8.3.1 实例方法.150 8.3.2 类型
15、方法.154 8.3.3 存储属性、局部变量和全局变量的区别.156 8.3.4 局部变量和存储属性同名的解决方法self属性.158 8.4 下标脚本.158 8.4.1 定义下标脚本.158 8.4.2 调用下标脚本.159 Swift 语言快速入门(内部资料) 版权所有 大学霸出品 6 8.4.3 使用下标脚本.159 8.5 类的嵌套.163 8.5.1 直接嵌套.163 8.5.2 多次嵌套.165 8.6 可选链接.167 8.6.1 可选链接的实现方式.167 8.6.2 通过可选链接调用属性、下标脚本、方法.168 8.6.3 连接多个链接.170 第 9 章 继承.171 9
16、.1 为什么使用继承.171 9.1.1 减少代码量.171 9.1.2 扩展功能.172 9.2 继承的实现.173 9.2.1 继承的定义.174 9.2.2 属性的继承.174 9.2.3 下标脚本的继承.175 9.2.4 方法的继承.176 9.3 继承的特点.177 9.3.1 多层继承.177 9.3.2 不可删除.179 9.4 重写.179 9.4.1 重写属性.179 9.4.2 重写下标脚本.182 9.4.3 重写方法.183 9.4.4 重写的注意事项.184 9.4.5 访问父类成员.185 9.4.6 阻止重写.188 9.5 类型检查.190 9.5.1 类型检
17、查is.191 9.5.2 类型检查as.192 9.5.3 AnyObject和Any的类型检查.194 第 10 章 枚举类型.196 10.1 枚举类型的组成.196 10.2 定义枚举类型.197 10.2.1 任意类型的枚举类型.197 10.2.2 指定数据类型的枚举类型.197 10.3 定义枚举类型的成员.198 10.3.1 定义任意类型的枚举成员.198 10.3.2 定义指定数据类型的枚举类型成员.199 10.3.3 注意事项.201 10.4 实例化枚举类型的对象.201 Swift 语言快速入门(内部资料) 版权所有 大学霸出品 7 10.5 访问枚举类型中成员的原
18、始值.202 10.5.1 通过成员访问原始值.202 10.5.2 通过原始值获取成员.203 10.6 枚举成员与switch匹配.205 10.7 相关值.206 10.8 定义枚举类型的属性.208 10.8.1 计算属性.208 10.8.2 类型属性.209 10.8.3 属性监视器.209 10.9 定义枚举类型的下标脚本.210 10.10 定义枚举类型的方法.211 10.10.1 实例方法.211 10.10.2 类型方法.213 10.11 枚举类型的应用.213 10.11.1 为常量/变量赋值.213 10.11.2 作为函数的参数.214 10.12 枚举类型嵌套.
19、215 10.12.1 直接嵌套.215 10.12.2 多次嵌套.216 第 11 章 结构.218 11.1 结构的定义和实例化.218 11.1.1 结构的构成.218 11.1.2 定义结构.218 11.1.3 实例化对象.219 11.2 定义结构的属性.219 11.2.1 存储属性.219 11.2.2 计算属性.221 11.2.3 类型属性.222 11.2.4 添加属性监视器.222 11.2.5 初始化实例对象.223 11.3 定义结构的下标脚本.225 11.4 定义结构的方法.226 11.4.1 实例方法.226 11.4.2 类型方法.227 11.5 结构嵌
20、套.228 11.5.1 直接嵌套.228 11.5.2 多次嵌套.229 11.6 类、枚举类型、结构的区别.230 11.7 类、枚举、结构的嵌套.231 11.7.1 枚举使用在类中.231 11.7.2 枚举使用在结构中.231 Swift 语言快速入门(内部资料) 版权所有 大学霸出品 8 11.7.3 类使用在结构中.232 第 12 章 构造方法和析构方法.233 12.1 值类型的构造器.233 12.1.1 默认构造器.234 12.1.2 自定义构造器.234 12.1.3 构造器代理.238 12.2 类的构造器.243 12.2.1 默认构造器.243 12.2.2 自
21、定义构造器.243 12.2.3 构造器代理.248 12.2.4 构造器的继承和重载.249 12.3 构造器的特殊情况.256 12.3.1 可选类型.256 12.3.2 修改常量属性.256 12.4 类的构造.257 12.5 设置默认值.259 12.5.1 在定义时直接赋值.259 12.5.2 在构造器中赋值.259 12.5.3 使用闭包设置属性的默认值.259 12.5.4 使用函数设置默认值.261 12.6 析构方法.261 12.6.1 理解析构.261 12.6.2 析构方法的定义.262 12.6.3 使用析构方法.262 12.6.4 构造方法和析构方法的区别.
22、264 第 13 章 扩展和协议.264 13.1 扩展.264 13.1.1 扩展的定义.264 13.1.2 扩展属性.265 13.1.3 扩展构造器.267 13.1.4 扩展方法.270 13.1.5 扩展下标脚本.272 13.1.6 扩展嵌套类型.273 13.2 协议.273 13.2.1 协议的定义.274 13.2.2 协议的实现.274 13.2.3 协议的成员声明属性.275 13.2.4 协议的成员声明方法.278 13.2.5 协议的成员声明可变方法.280 13.3 可选协议.281 13.3.1 定义可选协议.282 Swift 语言快速入门(内部资料) 版权所
23、有 大学霸出品 9 13.3.2 声明可选成员.283 13.3.3 调用可选协议.284 13.4 使用协议类型.286 13.4.1 协议类型作为常量、变量等的数据类型.286 13.4.2 协议类型的返回值或参数.287 13.4.3 协议类型作为集合的元素类型.287 13.5 在扩展中使用协议.288 13.5.1 在扩展中实现协议.288 13.5.2 定义协议成员.288 13.5.3 扩展协议声明.289 13.6 协议的继承.290 13.7 协议组合.291 13.8 检查协议的一致性.292 13.9 委托.293 第 14 章 自动引用计数(ARC).296 14.1
24、自动引用计数的工作机制.296 14.2 循环强引用的产生.298 14.2.1 类实例之间的循环强引用.298 14.2.2 闭包引起的循环强引用.300 14.3 循环强引用的解决方法.302 14.3.1 解决类实例之间的循环强引用.302 14.3.2 解决闭包引起的循环强引用.307 第 15 章 运算符重载.309 15.1 为什么使用运算符重载.310 15.2 算术运算符的重载.310 15.3 一元减/加运算符的重载.311 15.3.1 一元减运算符的重载.312 15.3.2 一元加运算符的重载.312 15.4 复合赋值运算符的重载.313 15.5 自增自减运算符的重
25、载.315 15.5.1 自增运算符的重载.315 15.5.2 自减运算符的重载.317 15.6 比较运算符的重载.319 15.6.1 “=”相等运算符的重载.319 15.6.2 “!=”不相等运算符的重载.320 15.6.3 其他比较运算符的重载.321 15.7 自定义运算符的重载.322 15.7.1 前置自定义运算符的重载.322 15.7.2 中置自定义运算符的重载.323 15.7.3 后置自定义运算符的重载.323 15.7.4 自定义运算符的优先级和结合性.325 Swift 语言快速入门(内部资料) 版权所有 大学霸出品 10 15.8 注意事项.331 15.8.
26、1 重载后运算符的优先级.331 15.8.2 不可以重载的运算符.333 第 16 章 泛型.333 16.1 为什么使用泛型.333 16.2 泛型函数.334 16.3 泛型类型.335 16.3.1 泛型枚举.335 16.3.2 泛型结构.336 16.3.3 泛型类.338 16.4 泛型类的层次结构.339 16.4.1 使用泛型基类.339 16.4.2 使用泛型派生类.340 16.5 具有多个类型参数的泛型.340 16.6 类型约束.341 16.7 关联类型.342 16.7.1 定义关联类型.342 16.7.2 扩展已存在类型为关联类型.344 16.7.3 约束关
27、联类型.346Swift 语言快速入门(内部资料) 版权所有 大学霸出品 第 8 章 类 虽然函数可以简化代码,但是当一个程序中出现成百上千的函数和变量时,代码还是会显得很混乱。为此,人们又引入了新的类型类。它是人们构建代码所用的一种通用、灵活的构造方式。本章将主要详细讲解类的使用。8.1 类与对象 类是一种新的数据类型,类似于生活中犬类、猫类等等。而对象则是将这个抽象的类进行了具体化。例如,在犬类中,有哈士奇,金毛等等,这些就是犬类的具体化,即对象。本节将讲解类的创建以及如何将类进行具体化(即实例化)为对象。8.1.1 类的组成 在一个类中通常可以包含如图 8.1 所示的内容。图 8.1 类
28、的构成 其中,这些内容的功能如下:属性:它将值和特定的类关联。下标脚本:访问对象、集合等的快捷方式。方法:实现某一特定的功能,类似于函数。8.1.2 创建类 在 Swift 中类的创建要比在 Objective-C 中简单的多。在 Objecttive-C 中,需要使用需要interface 和end 对类中的内容进行声明,还需要使用implementation 和end 对类声明的内容进行实现。在 Xcode 6 之前,它们需要放置在不同的文件中。虽然在 Xcode 6 中,它们可以放置在一个文件中,但是也相当的麻烦。Swift 语言推出了自己创建类的方式,只使用一个 class 关键字,其
29、一般的创建形式如下:Swift 语言快速入门(内部资料) 版权所有 大学霸出品 class 类名 具体内容 注意:在类中可以定义属性和方法,这些内容会在后面做详细的介绍。类名可以使用“大骆驼拼写法”方式来命名(如 SomeClass),以便符合标准 Swift 类型的大写命名风格(如String,Int 和 Bool)。对于后面所讲的对象、属性以及方法等可以使用“小骆驼拼写法”来命名。【示例 8-1】以下创建一个名为 NewClass 的类。代码如下:class NewClass 该类名称为 NewClass。由于其中没有属性和方法,所以它只是一个空类。8.1.3 实例化对象 实例化对象也可以
30、称为类的实例,其语法形式如下:var/let 对象名=类名()【示例 8-2】以下会创建一个类名为 NewClass 的类,然后再进行实例化。代码如下:import Foundation class NewClass let newClass=NewClass()注意:在进行实例化时,类名后一定要加上()。否则程序就会错误,如以下的代码:var newClass=NewClass 由于在实例化时缺少了(),导致程序出现以下的错误信息:Expected member name or constructor call after type name 以上所讲的这些只是简单的实例化对象。它使用了最简
31、单的构造器来生成一个对象。在后面的章节中我们会为开发者讲解构造器的具体用法。8.2 属性 在 Objective-C 中,属性是使用关键字property 关键字进行声明的内容。在 Swift 中,属性可以将值跟特定的类、结构或枚举关联。属性一般分为存储属性、计算属性和类型属性。本节将讲解对这些属性做详细的讲解。8.2.1 存储属性 存储属性就是存储特定类中的一个常量或者变量。根据数据是否可变,分为常量存储属性和变量存储属性。1.定义存储属性定义存储属性 常量存储属性使用 let 关键字定义(声明定义在一起进行,为了方便称为定义),其语法形式如下:Swift 语言快速入门(内部资料) 版权所有
32、 大学霸出品 let 常量存储属性名:数据类型=初始值 变量存储属性可以使用 var 关键字定义,其语法形式如下:var 变量存储属性名:数据类型=初始值【示例 8-3】以下代码定义类 NewClass1,其中包含两个属性 value1 和 value2,代码如下:class NewClass1 let value1=20 var value2:Int=10 其中,value1 使用 let 定义为常量存储属性,value2 使用 var 定义为变量存储属性。在定义存储属性时,初始值是必不可少的,否则,就会出现错误。例如,以下的代码:class NewClass1 let value1=20
33、var value2:Int 在此代码中,由于 value2 后面未加初始值,导致程序出现以下的错误信息:Class NewClass1 has no initializers 2.访问存储属性访问存储属性 对于这些存储属性的访问,需要使用“.”点运算符。其语法形式如下:对象名.常量存储属性名/变量存储属性名【示例 8-4】以下定义了 3 个存储属性 firstValue、secondValue、thirdValue,然后进行访问。代码如下:import Foundation class NewClass let firstValue:Int=0 let secondValue=200 var
34、 thirdValue:String=Hello let newclass=NewClass()/存储属性的访问 println(firstValue=(newclass.firstValue)println(secondValue=(newclass.secondValue)println(thirdValue=(newclass.threeValue)运行结果如下所示:firstValue=0 secondValue=200 thirdValue=Hello Program ended with exit code:0 注意:对存储属性进行访问时,只可以对在自己类中定义的存储属性进行访问,
35、否则就会出现错误,代码如下:import Foundation class NewClass1 var class1Value=10 class NewClass2 var class2Value=10 let newclass1=NewClass1()println(newclass1.class1Value)println(newclass1.class2Value)Swift 语言快速入门(内部资料) 版权所有 大学霸出品 在此代码中,由于 class2Value 存储属性是在 NewClass2 类中定义的,而不是 NewClass1中定义的,所以程序就会出现以下的错误信息:NewCl
36、ass1 does not have a member named class2Value 存储属性除了可以使用“.”点运算符进行读取外,还可以对其进行修改。修存储改属性的一般语法形式如下:对象名.存储属性=修改的内容【示例 8-5】以下代码就将 secondValue 的属性值Hello修改为了Swift,代码如下:import Foundation class NewClass var secondValue:String=Hello let newclass=NewClass()println(修改前:secondValue=(newclass.secondValue)newclass.
37、secondValue=Swift /修改存储实现 println(修改后:secondValue=(newclass.secondValue)运行结果如下所示:修改前:修改前:secondValue=Hello 修改后:修改后:secondValue=Swift Program ended with exit code:0 注意:只有变量存储属性才可以进行属性修改,常量存储属性不可以进行属性修改。如以下的代码:import Foundation class NewClass let firstValue:Int=0 let newclass=NewClass()println(修改前:fir
38、stValue=(newclass.firstValue)newclass.firstValue=100 /试图对属性 firstValue 的值进行修改 println(修改后:(newclass.firstValue)由于在类中使用了 let 对存储属性进行了定义,其值是不可以进行修改的,所以出现了以下的错误信息:Cannot assign to firstValue in newclass 3.延迟存储属性延迟存储属性 如果开发者只有在第一次调用存储属性时才能确定初始值,这时需要使用延迟存储属性实现。它的定义一般需要使用关键字lazy 实现的,其语法形式如下:lazy var 属性名:数
39、据类型=初始内容 注意:在延迟存储属性中初始内容是不可以省去的。数据类型也是可以省去的,因为swift 会根据初始内容自行判断数据类型。【示例 8-6】以下将使用lazy 来定义一个延迟存储属性 importer,代码如下:import Foundation class DataImporter var fileName=123456 class DataManager lazy var importer=DataImporter()var data=String()let manager=DataManager()manager.data+=Some more data Swift 语言快速
40、入门(内部资料) 版权所有 大学霸出品 println(manager.data)println(manager.importer.fileName)在没有调用 manager.importer.fileName 时,实例的 importer 属性还没有被创建。运行结果如下所示:Some more data 123456 Program ended with exit code:0 我们可以使用断点调试的方法对此代码进行调试,来查看它的运行结果。具体步骤如下:(1)为几行关键代码添加断点,如图 8.2 所示。图 8.2 添加断点(2)单击运行按钮,此时会在第一个断点处出现一个蓝色的箭头,表示此
41、行代码在运行。然后选择 Debug|Continue 命令,按下调试窗口工具栏中的 Continue program execution按钮,查看程序的执行,其中,可以使用查看器来观察属性值的变化。属性查看器位于调试信息窗口左半部分,如图 8.3 所示。程序的执行,如图 8.4 所示。其中,看到的 self、data、importer.storage(因为 importer 是延迟属性,为了和其他属性区分,所以在查看器上看到是importer.storage)等都是属性。它们会随程序的执行为改变。图 8.3 查看器位置 Swift 语言快速入门(内部资料) 版权所有 大学霸出品 图 8.4 调
42、试 Swift 语言快速入门(内部资料) 版权所有 大学霸出品 在此图中程序执行到第 3 步,也就是第三个图时,才为类 DataManager 的属性 data 初始化,但没有给 importer.storage 属性进行初始化,一直为 nil,直到执行到第 9 步,即第 9个图时,才为 importer.storage 属性的属性初始化。在定义一个延迟存储属性时需要注意以下 2 点,(1)定义一个延迟存储属性时除了lazy 外,还需要使用 var 关键字,但是不能使用let 关键字,否则程序就会出现错误,如以下代码:class DataImporter var fileName=123456
43、 class DataManager lazy let importer=DataImporter()var data=String()由于在定义延迟属性时使用了 let 关键字,所以导致程序出现了以下的错误:lazy attribute cannot be used on a let(2)初始内容是不可以省去的,否则程序就会出现错误,如以下的代码,定义了一个没有初始值的延迟属性。代码如下:class DataManager lazy var value:Int 由于在此代码中没有为 value 指定初始值,导致程序出现了以下的错误:lazy properties must have an i
44、nitializer 8.2.2 计算属性 除了存储属性外,类中还可以定义计算属性。计算属性不存储值,而是提供了一个 getter和 setter 来分别进行获取值和设置其他属性的值。getter 使用 get 关键字进行定义,其一般形式如下:get return 某一属性值 setter 使用 set 关键字进行定义,其一般语法形式如下:set(参数名称)属性值=某一个值 当然,它也可以没有参数名称。这种情况会后面的内容中讲解。在计算属性中同时包含了 getter 和 setter,其一般定义形式如下:var 属性名:数据类型 get return 某一属性值 set(参数名称)属性值=某一
45、个值 Swift 语言快速入门(内部资料) 版权所有 大学霸出品 【示例 8-7】以下代码定义了一个类 WalletClass,用来保存钱包中的金额,其默认单位为美元。为了方便用户以人民币为单位进行访问值和设置值,所以使用了计算属性 cal。代码如下:import Foundation class WalletClass var money=0.0 var cal:Double /定义计算属性 cal get /定义 getter var RMB=money*6.1 return RMB /返回以人民币为单位的金额 set(RMB)/定义 setter money=RMB/6.1 /返回以返回
46、以美元为单位的金额 var mywallet=WalletClass()mywallet.cal=(20)/输出 println(mywallet.cal)println(mywallet.money)运行结果如下所示:20.0 3.27868852459016 Program ended with exit code:0 注意:在使用计算属性时需要注意以下三点:1.定义计算属性的关键字定义计算属性的关键字 在定义一个计算属性时,必须且只能使用 var 关键字,否则就会出现错误。以下的代码,将示例 8-7 的代码做了一些修改,代码如下:class WalletClass var money=0
47、.0 let cal:Double get var RMB=money*6.1 return RMB set(RMB)money=RMB/6.1 在此代码中定义一个计算属性,但是使用了 let 关键字,导致程序出现了以下的错误:let declarations cannot be a computed property 2.数据类型数据类型 在定义计算属性时,一定要为属性指定一个明确的数据类型,否则就会出现错误提示。例如以下的代码,是将示例 8-7 中的代码做了一些修改。代码如下:class WalletClass Swift 语言快速入门(内部资料) 版权所有 大学霸出品 var money
48、=0.0 var cal /没有设置 cal 的数据类型 get var RMB=money*6.1 return RMB set(RMB)money=RMB/6.1 在此代码中由于没有为计算属性指定一个明确的数据类型,导致程序出现了以下的错误信息:Variable with getter/setter must have an explicit type 3.set 后面的参数类型后面的参数类型 在使用计算属性时,set 后面的参数类型要和返回值的类型相同,不需要再指定类型。否则,程序就会出现错误。如以下的代码,此代码是将示例 8-7 中的代码做了一下修改,代码如下:class Wallet
49、Class var money=0.0 var cal:Double /没有设置cal的数据类型 get var RMB=money*6.1 return RMB set(RMB:String)/为参数定义了数据类型 money=RMB/6.1 在此代码中,对 set 后面的参数 RMB 指定了数据类型,导致程序出现了以下的错误:Expected)after setter value name Expected to start setter definition 3.没有定义参数名称没有定义参数名称 如果计算属性的 setter 没有定义表示新值的参数名,则可以使用默认名称 newValue
50、。【示例 8-8】以下代码就使用了 newValue 来实现了华氏温度和摄氏温度的转换。代码如下:import Foundation class DegreeClass var degree=0.0 var cal:Double get var centigradedegree=(degree-32)/1.8 return centigradedegree set degree=1.8*newValue+32 /没有定义参数名称,可以使用默认的 Swift 语言快速入门(内部资料) 版权所有 大学霸出品 var degreeClass=DegreeClass()degreeClass.cal=