无意间看到自己以前学习swift的笔记,从近两年苹果的发布会,可以看出苹果推动swift的决心,OC更换为swift也是未来发展的趋势,想起当初自己钻研学习swift的痛苦的情景,现在把它们整理出来并与现在最新的swift结合以供初学者使用,让初学者少走弯路。有时间会陆续整理后面知识的学习笔记。
第一个 swift 项目
新建 swift 项目步骤和 oc 相同,只需要在建项目时,选择编程语言为 swift
打开 ViewController.swift 文件,键入以下代码,点击运行,执行我们的第一个单页面的 swift 项目。
//
import UIKit
//类的声明和实现,写在一个 .swift 文件里面
//用点语法替代了 oc 的 []语法
//对变量常量的定义取消了指针
//swfit 可以直接调用的 oc 的 Foundation 框架和 UIKit 框架的 api
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
//相当于 oc 的 [[UIView alloc] initWithFrame: CGRectMake(0, 20, 200, 200)]
let subView = UIView(frame: CGRect(x: 0, y: 20, width: 200, height: 200))
subView.backgroundColor = UIColor.blueColor()
view.addSubview(subView)
let button = UIButton(type: .Custom)
button.frame = CGRect(x: 10, y: 10, width: 50, height: 30)
button.backgroundColor = UIColor.purpleColor()
subView.addSubview(button)
button.addTarget(self, action: "buttonClick", forControlEvents: UIControlEvents.TouchUpInside)
}
func buttonClick() {
print("hello, world!")
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
总结
- 在 Swift 中没有了 main.m,@UIApplicationMain 是程序入口
- 在 Swift 中只有 .swift 文件,没有 .h/.m 文件的区分
- 在 Swift 中,一个类就是用一对 {} 括起的,没有 @implementation 和 @end
- 每个语句的末尾没有分号,在其他语言中,分号是用来区分不同语句的
- 在 Swift 中,一般都是一行一句代码,因此不用使用分号
与 OC 的语法快速对比
- 在 OC 中 alloc / init 对应 ()
- 在 OC 中 alloc / initWithXXX 对应 (XXX: )
- 在 OC 中的类函数调用,在 Swift 中,直接使用 .
- 在 Swift 中,绝大多数可以省略 self.,建议一般不写,可以提高对语境的理解(闭包时会体会到)
- Swift 中,枚举类型的前缀可以省略,如:.ContactAdd,但是:很多时候没有智能提示
- 监听方法,直接使用字符串引起
- 在 Swift 中使用 print() 替代 OC 中的 NSLog,效率更高!
playGround 介绍
- playGround 是 xcode6.0 之后推出的一个新功能,可以一边写 swfit 代码,一边即时结果,无需手动编译;
- playGround 是一款不错的 swfit 学习工具,如果开发项目,仍然需要新建项目。
- 由于playGround是即时编译,所以容易报错(电脑配置过低也容易报错),如果确认语法没错 ,需要重行启动playGround
基本语法
常量和变量
定义
- let 定义常量,一经赋值不允许再修改
- var 定义变量,赋值之后仍然可以修改
// 定义常量 let / 变量 var
// 格式: let/var 变量名: 类型 = 值
// 提示: Swift 提供了自动推导,如果使用默认的数据类型,: 数据类型
可以省略
// 格式: let/var 变量名 = 值,变量类型会根据右侧的结果自动推导
// 定义常量并且直接设置数值
let x: Int = 10
// 常量数值一经设置,不能修改,以下代码会报错
// x = 30
// 使用 : 类型
,仅仅只定义类型,而没有设置数值
let y: Int
// 常量有一次设置数值的机会,以下代码没有问题,因为 y
还没有被设置数值
y = 10
// 一旦设置了数值之后,则不能再次修改,以下代码会报错,因为 y
已经被设置了数值
// y = 50
print(x + y)
// 变量设置数值之后,可以继续修改数值
var z: Int
z = 100
z = 200
print(x + y + z)
类型自动推导
Swift能够根据右边的代码,推导出变量的准确类型
通常在开发时,不强制要求指定变量的类型,如果需要指定,可以在变量名后使用:,然后跟上变量的类型
重要技巧:Option + Click 可以查看变量的类型
没有隐式转换
Swift 对数据类型要求异常严格。在任何时候,都不会做隐式转换,如果要对不同类型的数据进行计算,必须要显式的转换。
let x = 100 //swfit 会自动推导 x 为整型
let y = 10.5 //swfit 会自动推导 y 为浮点型
let num = Double(x) + y
let num1 = x + Int(y)
let 和 var 的选择
应该尽量先选择常量,只有在必须修改时,才需要修改为 var
- 在 Xcode 7.0 中,如果没有修改变量,Xcode 会提示修改为 let
可选值
可选值(Optional) 是 Swift 的一大特色,也是 Swift 初学者最容易困惑(痛不欲生)的问题
所谓可选值(optional),就是指一个变量或常量,可能有值,也可能没有值。
场景举例:用一个值保存网络请求的数据;如果请求成功,则有值;如果请求失败,就没有值。
可选值的定义
定义常量/变量时,在类型后面加一个?表示该变量是可选的。
可选值必须提定类型
定义一个可选变量时,表示该变量可以有一个指定类型的值,也可以是 nil;变量可选项的默认值是 nil
常量可选项没有默认值,主要用于在构造函数中给常量设置初始数值
let x: Optional = 10
let y: Optional
let a: Int? //a默认没有值
var b: String? //b的默认值为 nil
let aa: Int? = 10 //aa
let bb: String? = "hello, world"
- 可选值解包
如果 Optional 值是 nil,不允许参与计算, 只有解包(unwrap)后才能参与计算
?告诉编译器:我是一个可选值,不要拿我做运算
!告诉编译器:我一定有值,快来使用我吧!一旦编译器解包后发现没有值,就会崩溃(比如说你女朋友过生日,你送给她一个iPhone10的盒子,她兴奋的打开,发现里面是空的,那就会生气发火)
如果不确定可选值是否有值,使用前,需要判断是否为nil
注意:必须要确保解包后的值不是 nil,否则会报错
- 常见错误
unexpectedly found nil while unwrapping an Optional value 翻译 在对可选项[解包]时发现 nil
可选绑定
由于可选项的内容可能为 nil,而一旦为 nil 则不允许参与计算。因此在实际开发中,经常需要判断可选项的内容是否为 nil
单个可选项判断
let url = NSURL(string: "http://www.baidu.com")
//: 方法1: 强行解包 - 缺陷,如果 url 为空,运行时会崩溃
let request = NSURLRequest(URL: url!)
//: 方法2: 首先判断 - 代码中仍然需要使用 !
强行解包
if url != nil {
let request = NSURLRequest(URL: url!)
}
//: 方法3: 使用 if let
,这种方式,表明一旦进入 if 分支,u 就不在是可选项
if let u = url where u.host == "www.baidu.com" {
let request = NSURLRequest(URL: u)
}
可选项条件判断
//: 1> 初学 swift 一不小心就会让 if 的嵌套层次很深,让代码变得很丑陋
if let u = url {
if u.host == "www.baidu.com" {
let request = NSURLRequest(URL: u)
}
}
>//: 2> 使用 where 关键字,
if let u = url where u.host == "www.baidu.com" {
let request = NSURLRequest(URL: u)
}
小结: if let 不能与使用 &&、|| 等条件判断 如果要增加条件,可以使用 where 子句 注意:where 子句没有智能提示
多个可选项判断
- 可以使用
,
同时判断多个可选项是否为空
let oName: String? = "张三"
let oNo: Int? = 100
if let name = oName {
if let no = oNo {
print("姓名:" + name + " 学号: " + String(no))
}
}
if let name = oName, let no = oNo {
print("姓名:" + name + " 学号: " + String(no))
}
判断之后对变量需要修改
let oName: String? = "张三"
let oNum: Int? = 18
if var name = oName, num = oNum {
name = "李四"
num = 1
print(name, num)
}
guard
guard 是与 if let 相反的语法,Swift 2.0 推出的
let oName: String? = "张三"
let oNum: Int? = 18
guard let name = oName else {
print("name 为空")
return
}
guard let num = oNum else {
print("num 为空")
return
}
// 代码执行至此,name & num 都是有值的
print(name)
print(num)
在程序编写时,条件检测之后的代码相对是比较复杂的,在判断的层次比较多的时候,使用 guard,减少嵌套的层次
if条件判断
Swift 中没有 C 语言中的非零即真概念
在逻辑判断时必须显示地指明具体的判断条件 true / false
if 语句条件的 () 可以省略
但是 {} 不能省略
let num = 200
if num < 10 {
print("比 10 小")
} else if num > 100 {
print("比 100 大")
} else {
print("10 ~ 100 之间的数字")
}
三目运算
Swift 中的 三目 运算保持了和 OC 一致的风格
x > 20 ? print("大了") : print("小了")
/**
'( )' 表示执行
*/
x > 20 ? print("真的大了") : ()
适当地运用三目,能够让代码写得更加简洁
判断可选值是否为 nil
让变量/常量强行解包参与运算会有风险,如果没有值,则会崩溃,所以在使用可选值时,最好先判断 可选值是否为 nil
var a: Int? = 10
var b = 10
if a != nil {
print("有值为\(a!+b)")
}else{
print("没有值")
}
?? 空合运算符
?? 运算符可以用于判断 变量/常量 的数值是否是 nil,如果是则使用后面的值替代
在使用 Swift 开发时,?? 能够简化代码的编写
var a: Int? = 10
var b = 10
if (a ! = nil) {
a = 0
}
let c = a + b
let d = (a ?? 0) + b
//注意:?? 的优先级低,在使用时,应该注意使用 ()
var str: String? = "小明"
// 注意 `??` 的优先级低,在使用时,应该注意使用 `()`
print((str ?? "无名") + " 你好")
print(str ?? "无名" + " 你好")
switch
switch 不再局限于整数
switch 可以针对任意数据类型进行判断
不再需要 break
每一个 case后面必须有可以执行的语句
要保证处理所有可能的情况,不然编译器直接报错,不处理的条件可以放在 default 分支中
每一个 case 中定义的变量仅在当前 case 中有效,而 OC 中需要使用 {}
let score = "优"
switch score {
case "优":
let name = "学生"
print(name + "80~100分")
case "良": print("70~80分")
case "中": print("60~70分")
case "差": print("不及格")
default: break
}
- 也可以作条件判断
var score = 80
switch score {
case let x where x < 60:
print("不及格")
case let x where x >= 60 && x < 70:
print("及格")
case let x where x >= 70 && x < 80:
print("良好")
case let x where x >= 80 && x < 90:
print("优秀")
case let x where x >= 90 && x <= 100:
print("牛逼")
default:
print("超过数值")
}
- 注意
如果条件没有覆盖所有的值,需要加default
for 循环
OC 风格的循环
var sum = 0
for var i = 0; i < 10; i++ {
sum += i
}
print(sum)
swift 风格的循环
- 0...10表示闭区间,数学中的[0,10]
- 0..<10表示开区间[0,10)
var sum = 0
//for-in,0..<10, 表示从0到9
for i in 0..<10 {
sum += i
}
for j in (0..10).reverse() {
print(j)
}
print(sum)
//范围 0...10 表示从0到10
sum = 0
for i in 0...10 {
sum += i
}
print(sum)
注意:..< 和 ... 用于定义 Range 类型,左右都不要添加空格
格式: for 变量 in 范围 { // 代码 }
省略下标,符号 '_'
for _ in 0...10 {
print("hello")
}