Swift初体验
//1.swift应用程序的入口
@UIApplicationMain
//2.swift中引用框架只需要引入框架的名字
import UIKit
//3.swift引用OC的框架方法名都一样,只是写法不一样
//4.swift类的所有的声名和实现都写在class最外层的大括号里面
//5.重写方法需要加上override
override func viewDidLoad() {
super.viewDidLoad()
}
//6.swift使用点语法调用一个方法
super.viewDidLoad()
swift单条语句不需要加分号
//var声明一个变量,let声明一个常量
let firstView = UIView(frame: CGRect(x: 10, y: 30, width: 200, height: 200))
基本数据类型
//: [Previous](@previous)
import Foundation
//基本数据类型
var a:Int = 10
var f:Float = 10.5
var d:Double = 100.5
var t:Bool = true
var fa:Bool = false
//douple元组:可以表示多个值的基本类型
var douple = (a,f)
var a1 = douple.0
var douple2 = (first: a,second: d)
var a2 = douple2.first
var a3 = douple2.0
//运算符
//赋值运算符 =
//算数运算符 + - * / %
//比较运算符 > < >= <= !=
//逻辑运算符 || &&
//三目运算符 ? :
//swift中特殊运算符
//?? 空合运算符
//_ 忽略运算符
//... 区间运算符
//0...5 代表>=0 && <=5
变量和常量
//1.用var来定义一个变量,用let定义一个常量
//变量一旦定义,其值可以改变,常量一旦定义,其值不可以改变
//如果不确定使用let还是var,可以先定义成let.报错时再改回来
var a:Int = 10
a = 5
let a1: Int = 15
//a1 = 20
//2.变量和常量可以根据等号右边的值,自动推导类型
var a3 = 15
let view = UIView()
var f = 10.5 //小数会被默认推断成Double类型
//3.swift对类型的要求极其严格,不同类型不能参与运算
//必须要强转
var result = Double(a3) + f
var result2 = a3 + Int(f)
控制流
//: [Previous](@previous)
import Foundation
//if条件语句的小括号可以省略,执行语句的大括号一定不能省略
var a = 10
if (a > 5) {
print("hello,world")
}
//使用for in + 区间运算符做循环
//0...10 [0,10]
//0..<10 [0,10)
for i in 0..<10 {
print(i)
}
//倒序遍历
//从10循环到0
for i in (0...10).reversed() {
print("love \(i)")
}
//忽略运算符 _:如果不想使用某个值,可以将该值忽略
for _ in 0...5 {
print("hello")
}
//while
//swift放弃了 ++ 和 -- 运算符
var i = 10
while i > 0 {
i -= 1
print("while \(i)")
}
//swift把do while 换成了repeat while
var m = 10
repeat {
m -= 1
print("repeat while\(m)")
} while m > 0
//switch
var score = 75
switch score {
case 60,75:
print("及格")
default:
print("仍需努力")
}
//可以判断任何类型
var scorestr = "75"
switch scorestr {
case "60":
print("及格")
default:
print("仍需努力2")
}
//可以做区间判断
//绑定:定义一个临时的变量或常量,把要判断的值赋值给该变量或常量,后面直接使用这个临时的变量或常量
//where是swift的关键,可以接条件判断语句
//default 如果case不能覆盖所有条件,则必须加default
//如果多个case同时满足条件,case的条件之间用逗号隔开
switch score {
case let score where score < 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:
print("牛逼")
default:
print("仍需努力")
}
可选值
//: [Previous](@previous)
import UIKit
//可选值:一个变量或常量,可能有值,可能没有值(nil),一个变量或常量有可能会被设为nil,那么这个值就叫可选值
//对于对象,OC可以将其设为nil
//OC会给变量赋初值,swift不会,swift默认不能将对象设为nil;swift中,如果将对象设为可选值,则任何数据类型都可以设为nil
var view: UIView?
view = nil
//在变量的数据类型后面接一个 ? 代表定义一个可选值
//一旦该变量设为可选,就代表该变量可以设为nil
//对于可选的变量,如果没有初始值,它的初始值为nil
var a:Int?
a = nil
//Optional :可选
var view1: UIView? = UIView()
print(view1)
//可选值不能直接参与运算,需要强制解包,在该值的后面接一个 !
//使用!时,如果该可选值为nil,则会崩溃
//value of optional type 'Int?' not unwrapped;提示使用一个可选值时需要强制解包
//unexpectedly found nil while unwrapping an Optional value 强制解包一个可选值时,发现其值为nil
//? 告诉编译器,我是一个可选值,不要拿我做运算
//! 告诉编译器,我一定有值,可以使用,一旦编译器发现没有值,就会蹦会
var b:Int? = 10
var c:Int? = 10
var result = b! + 10
//如果不确定可选值是否有值,需要先判断是否为nil
//1.直接判断,在使用可选值的时候,仍然需要使用!
if b != nil {
var result = b! + 10
}
//2.可选绑定
//对于可选值,条件判断语句中,定义一个临时的变量/常量 x,将可选值赋值给x,如果x有值,则绑定成功,后面可以直接使用,如果x没有值,则绑定不成功,可以异常处理;如果需要接条件判断,可以用逗号隔开
//可选绑定,使用可选值最广泛的用法
if let b = b,b > 15 {
var result = b + 10
}
//对多个可选值做可选绑定
if let b = b,let c = c {
var result = b + c
}
//可选值的使用
let url = URL(string: "http://www.baidu.com")
let request = URLRequest(url: url!)
if let url = url {
let request = URLRequest(url: url)
}
空合运算符
var a: Int? = 5
//空合运算符:在使用可选值时,如果可选值有值,则使用可选值的值,如果没有值,则使用空合运算符后面的值
//空合运算符的优先级比算数运算符低
var b = a ?? 10 + 3
字符串
//: [Previous](@previous)
import Foundation
//用var创建一个可变的字符串,用let创建一个不可变的字符串
//自变量创建
var str = "hello"
//构造方法创建
var str2 = String("hello2")
var str3 = String.init("hello3")
//字符串和字符串的拼接
var str4 = "hello,"
var str5 = "world"
var str6 = str4 + str5;
str4 += str5;
//字符串和常量,变量的拼接 \
var classIndex = 5
var str7 = "world"
var str8 = "hello\(str7)"
var str9 = "hello\(classIndex)"
//stringWithFormat
//05:05:05
let h = 5
let m = 5
let s = 5
var time = String(format: "%02d: %02d: %02d", h,m,s)
//字符串的比较
var str10 = "hello"
var str11 = "hello"
var str12 = "helll"
if str10 == str11 {
print("一样")
}
if str11 != str12 {
print("不一样")
}
//取字符串的长度
//let count = str12.lengthOfBytes(using: .utf8)
let count = str12.characters.count
//判断是否有前缀
if str12.hasPrefix("h") {
print("h开头")
}
if str12.hasSuffix("l") {
print("l结尾")
}
//正常情况下,swift的api可以解决问题,如果解决不了,可以将swift字符串转成oc字符串
let swiftStr = "hello,world"
//as代表类型转换
let ocString = swiftStr as NSString
ocString.substring(with: NSMakeRange(0, 5))
数组
//: [Previous](@previous)
import Foundation
//数组的创建
//用var创建一个可变的数组,用let创建一个不可变的数组
var array = ["dog","cat","pig"]
var emptyArr:[String] = []
array.append("fish")
//用初始化的方式创建数组,一定要指定类型
var array2: [String] = Array()
//数组的遍历
for item in array {
print(item)
}
//遍历同时拿到index
for item in array.enumerated() {
print("\(item.offset):\(item.offset)")
}
//倒序遍历
for item in array.reversed() {
print(item)
}
//数组的操作
//数组的合并
var array3 = ["goat","snake"]
var array4 = ["dog","cat","pig"]
var array5 = array3 + array4
//删除元素
let removed = array5.remove(at: 0)
//修改
array5[0] = "sheep"
//和OC的数组互转
let ocArray = array5 as NSArray
ocArray.subarray(with: NSMakeRange(0, 3))
字典
//: [Previous](@previous)
import Foundation
//定义一个字典
//用var定义一个可变的字典,用let定义一个不可变的字典
var dict = ["first":"dog","second":"cat"]
//定义一个空的字典
var dict1: [String: String] = Dictionary()
var dict2: [String: String] = [:]
//遍历字典
for (k,v) in dict {
print("key:\(k),value:\(v)")
}
//字典的操作,增删改查,字典的操作都是围绕key值做操作
//增
dict["third"] = "pig"
//删
dict["second"] = nil
//查:从字典中取出的值是一个可选值,使用的时候最好做一次可选绑定
let first = dict["first"]
//改
dict["first"] = "duck"
print(dict)
集合
//: [Previous](@previous)
import UIKit
//let定义不可变集合,var定义可变集合
//无序,不可重复
//空集合
var set: Set = []
var set1: Set = Set()
var Set2 = Set()
//增加元素
set.insert("a")
set.insert("b")
//创建一个带有默认值的集合
let set4: Set = ["cat","dog","cow"]
//集合的遍历
for item in set {
print(item)
}
//集合中删除一个元素
set.remove("a")
print(set)
//集合的交集,并集的判断
var setaa: Set = [1,2,3,4]
var setbb: Set = [1,2]
var setcc: Set = [3,4,5]
var setdd: Set = [1,2]
if setbb.isSubset(of: setaa) {
print("bb是aa的子集")
}
if setbb.isStrictSubset(of: setaa) {
print("bb是aa的真子集")
}
if setbb.isSuperset(of: setdd) {
print("bb是dd的交集")
}
函数
//: [Previous](@previous)
import Foundation
//用func来创建一个函数
//函数名后面接小括号,小括号不能省略
//小括号里面放参数,参数必须指定类型,多个参数用逗号隔开
//如果没有返回值,返回值的部分可以省略
func add(a:Int,b:Int) -> Int {
return a + b
}
let funcadd = add
//函数没有返回值,本质上返回一个空的元组
func addOne(a:Int,b:Int){
print(a + b)
}
func addTwo(a:Int,b:Int) -> (){
print(a + b)
}
func addThree(a:Int,b:Int) -> Void{
print(a + b)
}
let funcaddOne = addOne
//没有参数,没有返回值
func methodOne() {
print("hello,world")
}
//有参数,没有返回值
func methodTwo(a:Int,b:Int) {
print(a + b)
}
//有参数,有返回值,返回的值和返回值的类型必须保持一致
func methdThird(a:Int,b:Int) -> Int {
return a + b
}
//函数的调用
methodOne()
外部参数名
//: [Previous](@previous)
import Foundation
//函数的参数默认有一个外部参数名
//外部参数名:就是对参数做解释说明用的字符串
//默认情况下,swift会给每个参数加一个和形参一样的外部参数名
//外部参数名,就是对参数做解释说明的字符串
//外部参数名,在调用的时候,必须写
func add(a: Int,b: Int) {
return a + b
}
//add(a: <#T##Int#>, b: <#T##Int#>)
//也可以自定义外部参数名
func addOne(first a: Int,second b: Int){
return a + b
}
//addOne(first: <#T##Int#>, second: <#T##Int#>)
//也可以忽略外部参数名
//使用忽略运算符忽略外部参数名
func addTwo(_ a: Int,_ b: Int) {
return a + b
}
//addTwo(<#T##a: Int##Int#>, <#T##b: Int##Int#>)
函数默认参数
//: [Previous](@previous)
import UIKit
//swift语言函数的参数可以设默认值
//如果参数有默认值,则该参数可传,可不传
func add(a: Int,b: Int = 10) -> Int {
return a + b
}
add(a: 5)
add(a: 5, b: 15)
func customLabel(title: String, fontSize: CGFloat = 13,alignment: NSTextAlignment = .left,numberOfLines: Int = 0) -> UILabel {
let label = UILabel()
label.text = title
label.font = UIFont.systemFont(ofSize: fontSize)
label.textAlignment = alignment
label.numberOfLines = numberOfLines
return label
}
//let label = customLabel(title: <#T##String#>)
闭包的定义和调用
//: [Previous](@previous)
import Foundation
//闭包是一个匿名的函数快
//闭包被完成的包裹在大括号里面
//闭包的调用方式和函数一样
//闭包可以作为参数传递,也可以作为返回值
//闭包的定义和调用
//没有参数,没有返回值的闭包
let clousureOne = {
print("hello,world")
}
clousureOne()
//有参数,没有返回值
//参数和执行语句都写在大括号里面,用 in 隔开
//闭包没有外部参数名
let clousureTwo = {
(a: Int,b: Int) in
print(a + b)
}
clousureTwo(5,10)
//有参数,有返回值
let clousureThree = {
(a: Int,b: Int) -> Int in
return a + b
}
let result = clousureThree(3,4)
闭包的使用
//需求:下载movie,更新UI
//1.下载,定义成函数
//2.更新,使用闭包
//使用最多的场景:异步加载数据,加载完成之后刷新UI
//异步加载数据:定义成函数
//加载完成数据之后刷新UI,定义成闭包
//把闭包作为参数传递
//在函数中执行闭包
import UIKit
class ViewController: UIViewController {
func customLabel(title: String, fontSize: CGFloat = 13,alignment: NSTextAlignment = .left,numberOfLines: Int = 0,backgroundColor: UIColor = UIColor.yellow) -> UILabel {
let label = UILabel(frame: CGRect(x: 20,y: 40,width: 300,height: 40))
label.text = title
label.font = UIFont.systemFont(ofSize: fontSize)
label.textAlignment = alignment
label.numberOfLines = numberOfLines
label.backgroundColor = backgroundColor
return label
}
override func viewDidLoad() {
super.viewDidLoad()
let label = customLabel(title: "正在下载...")
view.addSubview(label)
// func updateUI(movieName: String){
// label.text = "\(movieName),下载完成"
// }
let updateUI = {
(movieName: String) in
label.text = "\(movieName),下载完成"
}
//下载电影,完成后更新UI
downloadMovie(callBack: updateUI)
}
func downloadMovie(callBack:@escaping (String) -> ()) {
//模拟异步加载数据
DispatchQueue.global().async {
Thread.sleep(forTimeInterval: 2)
let movieName = "电影"
DispatchQueue.main.async {
//刷新UI
callBack(movieName)
}
}
}
}
尾随闭包
//尾随闭包:当闭包表达式作为函数的最后一个参数的时候,可以把闭包写在小括号外面,如果函数的参数,只有闭包一个参数,则连小括号都可以省略
// DispatchQueue.global().async(execute: ??)
DispatchQueue.global().async {
Thread.sleep(forTimeInterval: 2)
let movieName = "电影"
DispatchQueue.main.async {
//刷新UI
callBack(movieName)
}
}
//下载电影,完成后更新UI
//downloadMovie(callBack: updateUI)
//尾随闭包的写法
downloadMovie {
(movieName: String) in
label.text = "\(movieName),下载完成"
}
guard的用法
//guard:保证
//guard:引导一个条件判断
//guard和if逻辑相同,写法相反
//if条件满足时,执行语句写在大括号里面,guard条件满足时,执行语句写在大括号外面,在大括号里面需要return,continue,break
//guard可以提前过滤条件不满足的情况,减少代码的层级
func testif() {
var a = 10
if a > 5 {
print("hello")
}
}
testif()
func testGuard() {
var a = 10
guard a > 5 else{
return
}
print("hello,world")
}
testGuard()
func testUrl() {
let url = URL(string: "http://www.baidu.com")
if let url = url {
let request = NSURLRequest(url: url)
}
guard let urls = url else {
return
}
let request = NSURLRequest(url: urls)
}
闭包的循环引用
downloadMovie {
//解除循环引用
//[weak self]时,代表self是可以被释放的,一旦释放,就代表self设为nil,self就是一个可选值
[weak self](movieName: String) in
label.text = "\(movieName),下载完成"
print(self!)
}