《Swift权威指南》分为两部分,第一部分主要介绍了Swift的基础语法。主要包括运算符、字符串、集合类、控制流、函数、枚举类型、类、结构体、属性、方法、下标、泛型、扩展、协议等内容。第二部分主要包括了如何使用Swift语言开发iOS平台的应用和游戏。最后给出了一个Flappybird游戏让读者了解使用Swift语言开发游戏的完整步骤。
为什么要写这本书
由于苹果公司一直以来以生产硬件文明,而在2014年的WWDC上竟然发布了一种新语言Swift。这一举动引起了业界不小的震动。而不到1个月时间里。Swift就挤进流行语言前列。这种以前从未发生过。
Swift目前可用于开发iOS和OS X平台的应用和游戏程序。但由于Swift刚诞生不久,中文资料还不多,而且Swift语言的强大和高开发效率,很有可能在将来取代Objective-C,成为iOS和OS X平台上的主流开发语言。所以为了让国内广大程序员能尽早与国际结果,我特意撰写了本书,以便可以让更多的人对Swift语言有所了解,更希望让更多的人成为国内乃至世界上第一批Swift语言专家。
本书分为如下两部分:
Swift语言基础部分(1至17章)
项目实战部分(18至20章)
其中第一部分主要介绍了Swift语言的基本语法,尤其是和其他语言不同的地方。第二部分主要介绍了如何使用Swift语言开发iOS平台的应用和游戏,在最后一章还给出了一个Flappybird游戏以供大家学习。
本书的特点
国内第一本介绍Swift的书
比较全面地介绍了Swift的语法
理论和实际相结合
读者对象
◎ 从事iOS平台应用和游戏开发的程序员。
◎ 对Swift语言感兴趣的程序员。
◎ 以前使用Objective-C,但想摆脱Objective-C繁琐的程序员
◎ 所以对新知识感兴趣的程序员。
◎ 源代码和工具下载
读者可以到我的Blog:http://blog.csdn.net/nokiaguy去下载相关的源代码和工具。
配套视频资源
由于目前Swift语言仍然是测试版,所以在读者拿到本书时,Swift的某些语法或API可能会有变化。为此,我在51CTO上开了关于Swift的视频课程,这套教材会随着Swift的更新而不断更新。
视频地址:http://edu.51cto.com/course/course_id-1387.html
Swift到底是怎样的一种语言
Swift 是一门博采众长的现代语言,在设计的过程中,Chris参考了Objective-C,Rust,Haskell,Ruby,Python,C#等优秀语言的特点,最终形成了目前 Swift 的语法特性。这也是为什么使用各种语言的程序员都能从Swift中找到自己熟悉的影子的原因。那么Swift语言到底是一种怎样的语言的。我们可以从下面几方面初步了解一下Swift语言。
Swift是面向对象的、编译型语言。编译时底层需要通过LLVM生成本地代码才能执行,所以效率还是很高的。
Swift可以使用Cocoa和Cocoa Touch中的API。这也就意味着Swift与Objective-C一样,拥有了一个强大的Framework Library。
Swift吸取了很多编程语言的优点,同时Swift又具备了很多动态语言的语法特性和交互方式,当然,Swift本身是静态语言。所以说,Swift尽可能地在静态语言和动态语言之间寻找平衡点。
既然说Swift是一种拥有动态特性的静态语言,那么Swift自然就是一门类型安全的语言。编译器可以在编译过程中检测出类型异常。例如,如果你期望为一个字符串变量赋值,那么类型安全机制会阻止你为这个变量设置整数。正是由于类型安全机制的存在,使开发者可以更早地发现并修复错误。
支持各种高级语言特性,包括闭包、泛型、面向对象、多返回值、类型接口、元组、集合等。
Swift 能与 Objective-C 进行混合编程 ,但代码分属不同的文件。
全面支持Unicode编码。也就是说,你可以用任何想用的字符作为变量名,例如,一个笑脸字符或汉字。图1-1就是使用笑脸图标和汉字作为变量名的一个典型例子。
使分号(;)变成了可选的符号。通常的静态语言,如Java、C#。每条语句结束后,都会在最后加上“;”,而Swift的每条语句不需要加“;”,当然,加上也没问题。只有在两条或多条语句写在同一行时才必须加“;”。
简化和增强了集合数据类型。用过Java和C#的读者知道。在这两种语言中,各种集合类型不可谓不全,但太多也有它不好的地方,就是不知道使用哪个。而且这些集合数据类型的功能也不够强大。在Swift语言中只提供了数组(Array)和字典(Dictionary)两个集合数据类型。其中Array类似List的功能,可以修改、添加、替换和删除数组元素。Dictionary类似Map的功能,用于存储Key-Value风格的值。
10. Swift可以通过元组实现函数返回多个值。这一功能在其他语言中需要通过返回一个对象或结构体(指针)来实现。
提供了优雅的闭包解决方案。例如,在排序函数sort中可以将函数作为参数值传递。下面的代码是一种典型的写法。
let array1 = ["X", "A", "1", "2", "Z"]
func backwards(s1: String, s2: String) -> Bool
{
return s1 > s2
}
var array2 = sort(array1, backwards)
当然,更简洁的写法是var array2 = sort(["X", "A", "1", "2", "Z"] ) { $0 > $1 },如果读者不明白这么写是什么意思,那么就继续往后看吧!Swift语言中提供了一种可选变量(Optional)。主要是为了应对一个变量可能存在,也可以是nil的情况。例如,将一个字符串(String)转换为整数(Int),但这个字符串是否可以成功转换为整数呢?如果不确定,就返回一个可选变量吧。如果成功转换,则返回正常的整数值,如果转换失败,则返回nil。实现的代码如下:
let str = "126CB5"
let value = str.toInt() // value是一个可选常量(用let声明是常量,用var声明是变量)
这时value就是一个可选变量。要想判断转换是否成功,可以使用下面的代码。
if value
{
// 如果value是可选变量,引用时需要加上“!”,
// 表示该选项变量中肯定有一个值
println(value!)
}
可选变量的引入解决了大部分需要显式处理的异常,这部分工作也扔给编译器去做了。
13、拥有不同意义的nil。在Swift 中的 nil 和 Objective-C 中的 nil 不同。在 Objective-C 中,nil 是指向不存在对象的指针,而在 Swift 里,nil 不是指针,它表示特定类型的值不存在。所有类型的可选值都可以被设置为nil,不仅仅是对象类型。
14、Swift 中没有从语言层面支持异步和多核,不过可以直接在 Swift 中复用 GCD(Grand Central Dispatch)的 API 实现异步功能。
- Swift没有一部处理机制。可能是认为有了可选变量,异常会很少使用,所以未加入异常处理。
瞧一瞧Swift到底长啥样
可能很多读者看到前面的介绍后跃跃欲试,想试一试Swift语言,不过先别忙,在正式编写Swift语言之前,先了解一下Swift语言的语法和样式是非常必要的。就像搞对象,起码得先看看对方长啥样,然后才能进行下一步。OK,现在就让我们看看Swift到底长啥样。
Swift语言和其他语言(如Java、C#、Objective-C)类似,也支持一些常规的操作和语法元素,例如,运算符(+、-、*、/、%、++、&&、||等)、数据类型(字符串、数值等)、控制语句(if、switch、for)、类、方法(函数)等。不过Swift添加了很多特有的语法元素(至少是大多数语言都不具备的技术),例如,类扩展、增强的switch语句、小标、元组类型、返回多种的方法(函数)等。下面是一段标准的Swift语言代码,尽管没有枚举Swift中所有的新特性,但足够让我们充分了解Swift语言的基本语法规则。如果读者对某些表达式不理解也没关系,在后面的章节会深入介绍这些特有的语法规则。
import Foundation
var value1 = 20 // 定义并初始化一个整型变量
value1 += 35
// 输出:value1=55
println("value1=(value1)")
let value2 = 42 // 定义并初始化一个整型常量
// 输出:97
println(value1 + value2)
// 定义并初始化一个数组变量
var array1 = ["abc","bbb","ccc"]
// 枚举数组中的每一个元素值
// 输出:abc bbb ccc
for element in array1
{
print(element + " ")
}
// 定义函数,返回值类型是String
func getPerson(name: String, age:Int) -> (String)
{
return "name:" + name + " age:" + toString(age)
}
println()
// 调用getPerson函数
let person = getPerson("bill", 50)
// 输出:person:name:bill age:50
println("person:(person)")
// 定义一个可以返回多个值的函数(返回两个值:name和price)
func getProduct() -> (name:String, price:Float)
{
return ("iPhone6", 6666.66)
}
// 输出:(iPhone6, 6666.66015625)
// 调用getProduct函数,并输出其返回值
println(getProduct())
// 输出:product name: iPhone6
// 输出getProduct函数返回值的name值
println("product name: (getProduct().name)")
// 定义Country类
class Country
{
var name = "China"
let area: Float = 960
// 定义一个成员方法
func getDescription() -> String {
return "Country:(name) Area:(area)"
}
}
// 创建一个Country类型的常量
let country = Country()
// 输出:Country:China Area:960.0
// 调用Country.getDescritpion方法,并输出该方法的返回值
println(country.getDescription())
// 定义一个类扩展,相当于将一个类的某一部分拿出来单独定义
extension Country
{
// 为Country类添加一个方法
func getAddress() -> (planet: String, location:String)
{
return ("Earth","Asia")
}
}
// 输出:Planet:Earth
// 调用扩展方法getAddress,并输出返回值中的planet
println("Planet:(country.getAddress().planet)")
// 输出:Location:Asia
// 调用扩展方法getAddress,并输出返回值中的location
println("Location:(country.getAddress().location)")
如果执行上面这段代码,会输出如下的信息。
value1=55
97
abc bbb ccc
person:name:bill age:50
(iPhone6, 6666.66015625)
product name: iPhone6
Country:China Area:960.0
Planet:Earth
Location:Asia
目录
第1章 Swift语言扫盲
1.1 Swift语言的前世今生
1.2 Swift到底是怎样的一种语言
1.3 Swift开发环境搭建
1.4创建Swift工程(OS X和iOS平台)
1.5瞧一瞧Swift到底长啥样
1.6 所见即所得的Playground
1.7 小结
第2章 Swift语言基础
2.1 Swift语句和分号
2.2变量和常量
2.2.1 定义和初始化
2.2.2 将变量和常量值插入字符串中
2.2.3变量和常量的命名规则
2.2.4 为变量和常量指定数据类型
2.3 数据类型
2.3.1 整数类型
2.3.2数制转换
2.3.3浮点类型
2.3.4 数值的可读性
2.3.5 数值类型之间的转换
2.3.7 类型别名
2.3.8 布尔类型
2.4 字符和字符串
2.4.1字符类型的常量和变量
2.4.2 字符串类型的常量和变量
2.4.3 枚举字符串中的所有字符
2.4.4 获取字符串中字符的Unicode编码
2.4.5字符串和字符的连接
2.4.6在字符串中包含特殊字符
2.4.7字符串之间的比较
2.4.8字符串的大小写转换
2.5 元组(tuples)类型
2.5.1 元组类型的定义
2.5.2 获取元组中的元素值
2.5.2 为元组中的元素命名
2.6 可选类型
2.7注释
2.8小结
第3章 基本操作符
3.1 操作符的种类
3.2 赋值操作符
3.3数值操作符
3.3.1 四则运算操作符
3.3.2 整数求余
3.3.3 浮点数求余
3.3.4 自增和自减
3.3.5 一元负号和正号
3.4 复合赋值操作符
3.5比较操作符
3.6 三元条件操作符
3.7 区间操作符
3.8逻辑操作符
3.8.1 逻辑非
3.8.2 逻辑与
3.8.3 逻辑或
3.8.4 组合逻辑
3.8.5 使用圆括号指定优先级
3.9小结
第4章 数组和字典
4.1 数组(Array)
4.1.1 创建和初始化数组
4.1.2 创建空数组
4.1.3 创建固定长度的数组
4.1.4 数组的加法
4.1.5 获取和设置数组元素值
4.1.6 数组区间赋值
4.1.7 添加和删除数组元素
4.1.8 枚举数组中的所有元素
4.2字典(Dictionary)
4.2.1 创建和初始化字典
4.2.2 创建空的字典
4.2.3 添加、修改和删除字典中的数据
4.2.4 获取字典中的值
4.2.5 将value转换为指定的类型值
4.2.6 枚举字典中的key和value
4.2.7 将keys和values转换位数组
4.3小结
第5章 控制流
5.1 for循环
5.1.1 对区间操作符进行循环
5.1.2 枚举数组和字典中的元素
5.1.3 枚举字符串中的所有字符
5.1.4 条件增量for循环语句
5.2while和do...while循环
5.2.1 while循环
5.2.2 do...while循环
5.3条件语句(if和switch)
5.3.1 if条件语句
5.3.2 switch条件语句的基本用法
5.3.3 fallthrough语句
5.3.4使用区间操作符进行条件匹配
5.3.5 使用元组进行条件匹配
5.3.6 where子句
5.4 在控制流中使用的控制语句(continue和break)
5.5 可跳转的标签
5.6小结
第6章 函数
6.1 函数的定义和调用
6.2返回多值的函数
6.3扩展参数
6.4扩展参数和内部参数合二为一
6.5 默认参数值
6.6可变参数
6.7 常量和变量参数
6.8 输入输出参数
6.9函数类型
6.10 嵌套函数
6.11小结
第7章 闭包
7.1 闭包表达式
7.1.1 使用闭包表达式代替回调函数
7.1.2 省略参数类型
7.1.3 省略返回值类型
7.1.4 省略return语句
7.1.5 既然都一样,那就去掉一个
7.1.6 直接给跪了!连骨架都没了
7.2 尾随闭包
7.3捕获值
7.4闭包是引用类型
7.5小结
第8章 枚举类型
8.1 枚举类型的语法格式
8.2 匹配枚举成员
8.3组合枚举成员
8.4设置枚举成员的原始值
8.5小结
第9章 类和结构体
9.1 类和结构体基础
9.1.1 类和结构体的异同点
9.1.2 定义类和结构体
9.1.3 创建类和结构体实例
9.1.4 访问和设置类和结构体成员的值
9.1.5 值类型和引用类型
9.1.6 判断两个变量或常量引用了同一个类对象
9.1 属性
9.1.1 存储属性
9.1.2 惰性存储属性
9.1.3 可读写的计算属性
9.1.4 只读计算属性
9.1.5 属性观察器
9.1.6 静态属性
9.3 方法
9.3.1 实例方法
9.3.2 方法的局部参数名和外部参数名
9.3.3 为方法的第一个参数增加外部参数名
9.3.4 类型中的self
9.3.5 方法的变异(mutating)
9.3.6 类型方法
9.4 构造器
9.4.1 没有参数的构造器
9.4.2构造器重载
9.4.3 构造器的内部参数和外部参数
9.4.4 默认构造器
9.4.5 结构体的逐一成员构造器
9.5 析构器
9.6 为类和结构体增加下标(Subscript)操作
9.7小结
第10章 类的继承
10.1 如何继承一个父类
10.2 重写方法
10.3 重写属性
10.4重写属性观察器
10.5方法被重写
10.6 构造器在继承中的调用规则
10.6.1 构造器和便利构造器
10.6.2 指定构造器和便利构造器是如何继承的
10.6.3 为什么子类必须调用父类的构造器
10.7小结
第11章 ARC机制
11.1 ARC的工作原理
11.2测试ARC在内存管理中所起到的作用
11.3解决循环强引用问题
11.3.1 什么是循环强引用
11.3.2 弱引用
11.3.3 无主引用
11.4闭包引起的循环强引用
11.5小结
第12章 可选链
12.1 什么是可选链
12.2使用可选链访问属性
12.3使用可选链调用方法
12.4 使用可选链调用下标
12.5多层连续使用可选链
12.6对方法返回值执行可选链
12.7小结
第13章 类型转换
13.1 类型转换概述
13.2 类型检测
13.3类型强行转换
13.4AnyObject和Any的类型转换
13.4.1 AnyObject类型
13.4.2 Any类型
13.4 小结
第14章 扩展
14.1 什么是扩展
14.2扩展语法
14.3扩展计算型属性
14.4扩展构造器
14.5扩展方法
14.6修改实例方法
14.7扩展下标
14.8扩展嵌套类型
14.9小结
第15章 协议
15.1 协议的语法
15.2协议中的成员
15.2.1 属性
15.2.2 方法
15.2.3 突变方法
15.3协议类型
15.4委托(Delegate)
15.5在扩展中添加成员
15.6通过扩展补充协议声明
15.7集合中的协议类型
15.8继承协议
15.9协议合成
15.10 校验协议的一致性
15.11可选协议的约定
15.12小结
第16章 泛型
16.1 泛型解决的问题
16.1.1 引出问题
16.1.2 泛型函数
16.2 类型参数
16.3泛型类型
16.4扩展泛型类型
16.5类型约束
16.5.1 类型约束语法
16.5.2 类型约束行为
16.6关联类型
16.6.1 关联类型行为
16.1.2 扩展一个存在的类型为一指定关联类型
16.7Where 语句
16.8小结
第17章 高级操作符
17.1 位操作符
17.1.1 按位取反操作符
17.1.2 按位与操作符
17.1.3 按位或操作符
17.1.4 按位异或操作符
17.1.5 按位左移/右移操作符
17.2溢出操作符
17.2.1 值的上溢出
17.2.2 值的下溢出
17.2.3除零溢出
17.3优先级和结合性
17.4操作符函数
17.4.1 二元操作符函数
17.4.2 前置和后置操作符函数
17.4.3 组合赋值操作符函数
17.4.4等值操作符函数
17.4.5 定制操作符
17.4.6 自定义中置操作符的优先级和结合性
17.5 小结
第18章 Swift开发iOS应用基础
18.1 创建iOS工程
18.2 iOS工程概述
18.2.1 应用程序代理
18.2.2 视图控制器
18.2.3 故事板
18.2.4 图像集合
18.3运行iOS应用
18.4实现一个可以浏览Web页面的程序
18.4.1 调整故事板的大小
18.4.2在故事板中设计UI
18.4.3 UI与视图控制器关联
18.4.4 浏览网页
18.4.5 改变视图控制器
18.5小结
第19章 SpriteKit游戏引擎基础
19.1 创建游戏工程
19.2游戏工程的结构
19.3运行游戏工程
19.4默认游戏工程原理解析
19.4.1 游戏的入口点
19.4.2 创建初始化
19.4.3 捕捉屏幕的触摸动作
19.5小结
第20章游戏项目实战:Flappybird
20.1 游戏效果演示
20.2 添加游戏资源
20.3游戏的初始化
20.4创建一对管道
20.5 通过触摸屏幕让小鸟跳起
20.6用物理引擎进行碰撞检测
20.7小结