常量和变量
// 定义常量与变量
// Option + click 可以查看变量/常量的类型
/**
- 使用 `let` 定义常量
- 使用 `var` 定义变量
- Swift 中 使用 Int 对应 NSInteger, Double --> CGFloat
- 自动推导:系统会根据等号后面的值,推断出前面变量(常量)的类型
- 指定变量/常量的类型,在名字后面加上 `:类型`
- 不同类型之间不允许直接计算(必须要转成相同类型)
- 先使用 let ,如果这个值需要改变的话,再更改成 var
- 空格大法:运算符左右的空格一定要对称
*/
func demo1(){
let a: Double = 10
// 常量不允许更改
// a = 20
print(a)
var b = 15
print(b)
// 更改
b = 20
print(b)
// 不同类型之间不允许直接计算
// let result = a + b
let result = Int(a) + b
print(result)
}
可选项
// 可选项 Optional
/**
- 在 Swift ,变量(常量)可能有值,可能为 nil,称为可选
- 使用 `?` 标识某个值是一个可选的值
- 可选项的值不能直接进行运算
- 使用 `!` 向系统表明,我这个 a 里面一定有值 (强行解包)
- 我们需要思考 `!` 标识的变量里面是否真的有值
- "unexpectedly found nil while unwrapping an Optional value" --> 对一个值为 nil 的可选项进行强制解包
- `??` 用于判断 可选值 是否为空,如果为空并提供一个默认值
*/
func demo2(){
// 定义一个可选值
var a: Int? = 10
let b = 10
// 报错的原因,如果 a 为nil,不能直接相加
// 方式1:如果 a 不为 nil 才进行运算
if (a != nil) {
let result = a! + b
print(result)
}
// 方式2:使用 `??`
// 如果 `??` 前面的变量/常量 是一个nil的话,就使用 `??` 后面的值进行运算
let result = b + (a ?? 0)
print(result)
}
// 定义常量与变量
// Option + click 可以查看变量/常量的类型
/**
- 使用 `let` 定义常量
- 使用 `var` 定义变量
- Swift 中 使用 Int 对应 NSInteger, Double --> CGFloat
- 自动推导:系统会根据等号后面的值,推断出前面变量(常量)的类型
- 指定变量/常量的类型,在名字后面加上 `:类型`
- 不同类型之间不允许直接计算(必须要转成相同类型)
- 先使用 let ,如果这个值需要改变的话,再更改成 var
- 空格大法:运算符左右的空格一定要对称
*/
func demo1(){
let a: Double = 10
// 常量不允许更改
// a = 20
print(a)
var b = 15
print(b)
// 更改
b = 20
print(b)
// 不同类型之间不允许直接计算
// let result = a + b
let result = Int(a) + b
print(result)
}
控制流
// if
/**
- Swift中,条件语句可以不使用 `()` 括起来
- Swift中,`{}` 必须写
- 没有 OC 中的 `非0即真` 的概念 --> true/false
*/
func demo1(){
let a = 10
if a > 5 {
print("a大于5")
}
}
//------------------------------------------------
// 判断可选值: if let
/**
// 方式2: if let: 会判断 url 是否有值
// - 如果有值,把值赋值给 u,并且进入到 if 括号内部
// - 如果没有值,不会赋值,也不会执行括号内部的代码
*/
func demo2(){
let url = NSURL(string: "http://www.baidu.com/")
// 方式1:
// if url != nil {
// let request = NSURLRequest(URL: url!)
// print(request)
// // 如果以下会大量使用 url 的话,都需要强制解包
// }
// 方式2: if let: 会判断 url 是否有值
// - 如果有值,把值赋值给 u,并且进入到 if 括号内部
// - 如果没有值,不会赋值,也不会执行括号内部的代码
if let u = url {
// 代码执行到这个地方, url 不为空, u 一定有值
let request = NSURLRequest(URL: u)
print(request)
// 如果以下要大量使用的话,可以直接使用 u
}
}
//------------------------------------------------
// if let 配合 where
// where: 给前面 let 的常量 多加一个条件判断
func demo3(){
let url = NSURL(string: "http://www.baid.com/")
// 判断 url 不为空并且其 host 为 `www.baidu.com` 再初始化 request
// 方式1:
if url != nil {
if url!.host == "www.baidu.com" {
let request = NSURLRequest(URL: url!)
print(request)
}
}
// 方式2:
if let u = url where u.host == "www.baidu.com" {
let request = NSURLRequest(URL: u)
print(request)
}
}
//------------------------------------------------
// guard let
// 与 if let 相反
// 可以减少 `{}` 嵌套
func demo4(){
let url = NSURL(string: "http://www.baid.com/")
guard let u = url else {
print("url为nil")
return
}
// 代码执行到这个地方,就代表 url 一定有值
let request = NSURLRequest(URL: u)
print(request)
}
//------------------------------------------------
//switch
/**
- 可以不用写 break,但是,case 下面必须跟上一条语句
- 在 OC 中,switch 只能判断整形,Swift 中可以判断任意类型
- Swift 中 case 里面定义变量/常量可以不用加 `{}` 指明作用域,只在当前 case 内部有效
*/
func demo5(){
let scroeStr = "优"
switch scroeStr {
case "优":
print("大于90分")
let s = "哈哈"
print(s)
case "良":
print("大于80分小于90分")
case "中":
print("大于60分小于80分")
case "差":
print("小于60分")
default :
print("其他")
}
}
//------------------------------------------------
// switch 判断
func demo6(){
let score = 95
// 如果大于90分,输出 `优`,其他类似
switch score {
// case 里里定义一个 s ,记录当前判断的值,where 添加一个条件判断
// // 如果不使用 s ,可以使用 `_` 占位
case let s where s >= 90:
print("优")
case let s where s >= 80 && s < 90:
print("良")
case let s where s >= 60 && s < 80:
print("中")
case let s where s < 60:
print("差")
}
}
循环
// for 循环
func demo1(){
/*
for (int i=0; i<10; i++) {
NSLog(@"%zd",i);
}
*/
// 仿 oc 写法
for (var i = 0; i < 10; i++) {
print(i)
}
print("============")
// Swift 特有的写法
// 指定的范围是: 0到10,不包括10 --> [0,10)
for _ in 0..<10 {
print("哈哈")
}
print("============")
// 指定的范围是: 0到10,包括10 --> [0,10]
for i in 0...10 {
print(i)
}
}
//---------------------------------------------
// while --> 能看得懂
func demo2(){
var i = 10
// 实现循环一次减 1 ,如果 i<=0 的时候就不循环
while (i > 0) {
i--
print(i)
}
// do -- while -> 更改成 repeat while
repeat {
i--
print(i)
}while (i > 0)
}
字符串操作
// 截取字符串
func demo4(){
let str = "听说下雨天音乐和辣条更配哟"
// fromIndex 是从指定位置开始截取,直到末尾
// 下雨天音乐和辣条更配哟
let result1 = str.substringFromIndex("哈哈".endIndex)
print(result1)
// 截取结果为:听说下雨天音乐和辣条更
// toIndex:从开始截取直接到指定的位置
let result2 = str.substringToIndex(str.endIndex.advancedBy(-2))
print(result2)
// 截取结果为:下雨天音乐和辣条更
// WithRange: 截取指定范围
let startIndex = "哈哈".endIndex
let endIndex = str.endIndex.advancedBy(-2)
let result3 = str.substringWithRange(startIndex..<endIndex)
print(result3)
// 因为 String 的截取字符串的方式,更改频率较大
// 如果记不住,可以把 String 转成 NSString 使用
let ocStr = str as NSString
print(ocStr.substringWithRange(NSMakeRange(0, 2)))
}
// 拼接字符串
func demo3(){
// 第1种方式
let name = "老王"
let result1 = "我叫" + name
// 输出结果是: 我叫老王
print(result1)
// 第2种方式
// 格式: "\(_变量名_)"
let result2 = "我叫\(name)"
print(result2)
let h = 8
let m = 20
let s = 3
// --> 08:20:03
let result3 = String(format: "%02d:%02d:%02d", arguments: [h, m, s])
let result4 = String(format: "%02d:%02d:%02d", h, m, s)
print(result3)
print(result4)
}
// 字符的长度的计算
func demo2(){
let str = "别哭泣,老王会笑"
// 取长度 --> 用得最多的方式
print(str.characters.count)
// 取 uft8 编码格式下的字节长度
print(str.utf8.count)
// 取指定编码格式的字节串长度
print(str.lengthOfBytesUsingEncoding(NSUTF8StringEncoding))
}
// 字符串的直接遍历
func demo1(){
let str = "别低头,绿帽会掉"
// 每一个字符的遍历
for c in str.characters {
print(c)
}
}
集合操作(数组和字典)
// 字典的合并
func demo7(){
var dict1 = ["name": "老王", "age": 18]
let dict2 = ["no": "哈哈", "name": "老李"]
print(dict1)
// 字典的合并
for (k,v) in dict2 {
// 赋值的时候,如果 dict1 里面有当前遍历到的 key 的话会直接覆盖
dict1[k] = v
}
print(dict1)
}
// 字典的遍历
func demo6(){
let dict1 = ["name": "老王", "age": 18]
for (k,v) in dict1 {
print("键:\(k);值:\(v)")
}
}
// 字典的定义以及初始化
// 使用 let 定义不可变的字典
// 使用 var 定义可变的字典
func demo5(){
// [String : NSObject] 以后开发中,用得最多的类型
// key: Value,使用 `,` 分割多个键值对
var dict1 = ["name": "老王", "age": 18]
// 添加一个键值对
dict1["no"] = "哈哈"
print(dict1)
// 通过这种方式设置值,如果字典里面已经存在对应的 key,会覆盖原值
dict1["name"] = "老李"
print(dict1)
// 移除对应的键值对
dict1["name"] = nil
print(dict1)
// 取值
let result = dict1["age"]
print(result)
// 初始化一个空的字典
var dict2 = [String: NSObject]()
dict2["a"] = "a"
print(dict2)
}
// 数组的容量
func demo4(){
var array = [Int]()
for i in 0..<128 {
array.append(i)
print("当前数组的长度是:\(array.count);容量是 \(array.capacity)")
}
}
// 数组的拼接
func demo3(){
var array1 = ["老王"]
let array2 = ["老李", "老张"]
print(array1)
// array1 += array2
array1 = array1 + array2
print(array1)
}
// 数组的遍历
func demo2(){
let array = ["老王", "老李", "老张"]
// 第 1 种
for (var i = 0; i < array.count; i++) {
print(array[i])
}
print("========")
// 第 2 种:只关心遍历的值
for value in array {
print(value)
}
// 第 3 种 : 关心遍历的脚标以及值
for (index,value) in array.enumerate() {
print("当前遍历的 index 是:\(index),值是:\(value)")
}
}
/// 数组的定义以及初始化
/**
- let 定义不可变数组
- var 定义可变数组
- 初始化空数组:数组类型() ---> 数组类型: [元素类型]()
*/
func demo1(){
// Swift 中,整数可以直接放在数组的初始中化中
var array1 = ["老王", 18]
array1.append("老李")
print(array1)
// 数组取值与 OC 中一样
let result = array1[0]
print(result)
// 初始化空数组
var array2 = [NSObject]()
array2.append("哈哈")
array2.append(18)
// 如果数组类型是 NSObject 的话,不能直接往里面添加结构体
// array2.append(CGRectZero)
var array3 = [Int]()
array3.append(1)
array3.append(2)
array3.append(4)
array3.append(6)
array3.append(2)
print(array3)
// 数组的移除
array3.removeFirst()
print(array3)
array3.removeAtIndex(3)
print(array3)
}
函数
// 在函数内部可以定义另外一个函数
func demo1(){
func test(){
print("执行 test 方法了")
}
test()
}
// 带有参数与返回值的函数
// 格式: func 函数名(外部参数1名 参数1名: 参数1的类型, ...) -> 返回值类型 {}
func sum4(num1 a: Int, num2 b: Int) -> Int {
return a + b
}
// 带有外部参数的函数
// 外部参数:提供给调用者使用的,让调用都更加明确函数的语意
// 格式: func 函数名(外部参数1名 参数1名: 参数1的类型, ...) {}
func sum3(num1 a: Int, num2 b: Int) {
let result = a + b
print(result)
}
// 带有参数的函数
// 格式: func 函数名(参数1名: 参数1的类型, ...) {}
func sum2(a: Int, b: Int) {
let result = a + b
print(result)
}
// 定义一个函数,函数里面打印一句话
// 没有参数没有返回值的函数
// 格式是: func 函数名() { __函数执行的代码__ }
func sum1() {
print("哈哈")
}
闭包
/**
- 与 OC 中的 block 类似
- 也是一个预先定义好的`代码块`
- 在需要的时候执行
- 也 block 一样,也是会涉及到循环引用的
- 可以函数的参数,还可以作为函数的返回值
*/
// 函数没有返回值的三种写法与闭包一样
// 只要能看懂
func demo5() -> Void {
}
// 闭包没有返回值的三种情况
func demo4(){
// 啥都不写
let clourse1 = { (num1 a: Int, num2 b: Int) in
let result = a + b
print("打印输出:\(result)")
}
// -> ()
let clourse2 = { (num1 a: Int, num2 b: Int) -> () in
let result = a + b
print("打印输出:\(result)")
}
// -> Void
let clourse3 = { (num1 a: Int, num2 b: Int) -> Void in
let result = a + b
print("打印输出:\(result)")
}
}
// 定义一个带有参数以及返回值的闭包
func demo3B(){
// 格式: let 闭包名 = {(参数列表) -> 返回值类型 in __闭包的执行代码__}
let clourse = { (num1 a: Int, num2 b: Int) -> Int in
let result = a + b
return result
}
let result = clourse(num1: 10, num2: 20)
print(result)
}
func demo3A(){
// 定义一个有参数的函数
func sum(num1 a: Int, num2 b: Int) -> Int{
let result = a + b
return result
}
// 执行函数接受返回值
let result = sum(num1: 10, num2: 20)
print(result)
}
// 定义一个有参数没有返回值的闭包
func demo2B(){
// in 用于区分闭包的参数和闭包的执行代码用的
// 格式:let 闭包名 = {(参数列表) in __闭包的执行代码__}
let clourse = { (num1 a: Int, num2 b: Int) in
let result = a + b
print("打印输出:\(result)")
}
clourse(num1: 10, num2: 20)
}
func demo2A(){
// 定义一个有参数的函数
func sum(num1 a: Int, num2 b: Int){
let result = a + b
print("打印输出:\(result)")
}
sum(num1: 10, num2: 20)
}
// 使用 闭包 实现 demo1A 的功能
func demo1B(){
// 定义一个没有参数没有返回值闭包
let clourse = {
print("闭包打印")
}
clourse()
}
func demo1A(){
func sum(){
print("打印输出")
}
sum()
}
闭包的基本使用
func text() {
// 网络请求完成之后执行的闭包
let clourse = { (response: String) -> () in
print("数据请求完毕:\(response)")
print("更新ui")
}
// 加载数据,传入数据加载完成要执行闭包
loadData(clourse)
}
func demo1(){
// 尾随闭包:如果闭包是参数里面最后一个参数,那么参数的括号可以提前关闭,闭包可以写在外面
dispatch_async(dispatch_get_global_queue(0, 0)) {
}
// 闭包放在括号内部
dispatch_async(dispatch_get_global_queue(0, 0), {
})
}
// 这个方法是专门用来加载数据的
func loadData(callback: (response: String) -> ()){
// 模拟异常加载数据
dispatch_async(dispatch_get_global_queue(0, 0)) {
// 执行耗时操作
NSThread.sleepForTimeInterval(2)
// 模拟请求回来的数据
let response = "办证 138xxxxx"
dispatch_async(dispatch_get_main_queue(), {
// 在主线程里面执行的代码,比如 更新 UI
// 把请求回来的数据通过闭包的方式把数据回调到外面
print(response)
callback(response: response)
})
}
}