• Swift 学习笔记


    Swift 学习笔记

    iOS开发学习中的简单记录

    Swift基本语法

    注释

    //
    /*
    多行注释
    */
    
    • 1
    • 2
    • 3
    • 4

    let 初始化后无法修改
    var 初始化后可修改

    let name1//常量
    var name2//变量
    
    • 1
    • 2

    运算符

    运算符​+​、​-​​*​、​/​、​%​ 、​+=​、​-=​​*=​​/=​
    逻辑运算符 ​Bool​​&&​、​||​​!​
    数据类型 Int​​Double​、​Bool​、​String​、​String()​​\()​
    判断运算符 ==!=
    用于判断运算符两边的指针是否相同 ===!==

    let num = 1
    let num2 : Int = 1 //说明数据类型
    let day = "5"
    let output = "星期" + day
    
    
    • 1
    • 2
    • 3
    • 4
    • 5

    **字符串插值 String Interpolation **

    省略+

    var day = "5"
    let output = "星期" + day + ",快放假了!"
    let newOutput = "星期\(day),快放假了" //省略
    
    • 1
    • 2
    • 3

    函数

    定义及使用

    定义函数时使用:指定类型
    调用函数时使用:指定参数值

    func sayHi(){
    	print("Hi")
    }
    func sayHi(name: String){
    	print("Hi\(name)")
    }
    sayHi(name: "Liu")
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    参数标签、默认值、返回值

    参数标签,函数传值默认为参数名,有参数标签就通过参数标签传值,_代表省略标签,直接传入值。

    //不要参数标签
    func sayHi_1(_ name : String){
        print("Hi \(name)")
    }
    sayHi_1("Liu")
    
    //默认值
    func sayHi_2(n name : String, age : Int = 0){
        print("Hi \(name) \(age)")
    }
    sayHi_2(n: "Liu",age: 2)
    
    //返回值
    func sayHi_3(n name : String, age : Int = 0) -> String{
        "Hi \(name) \(age)" // return "Hi \(name) \(age)"仅包含一个可返回的值可省略
    }
    print(sayHi_3(n: "Liu"))
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    函数重载 Function Overload

    根据传参的不同调用同名但功能不同的函数

    func driveForward() {
        print("move.....")
    }
    func driveForward(meters: Int) {
        print("move.....\(meters)")
    }
    driveForward() //move.....
    driveForward(meters: 10) //move.....10
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    函数返回值

    指定函数返回值数据类型 func() -> 返回值数据类型{}
    仅包含一个可以返回的数值,可省略return

    func sayHi_3(n name : String, age : Int = 0) -> String{
        "Hi \(name) \(age)" // return "Hi \(name) \(age)"
    }
    print(sayHi_3(n: "Liu"))
    
    • 1
    • 2
    • 3
    • 4

    函数的格式

    在这里插入图片描述

    数组

    在这里插入图片描述
    定义数组

    var weightArray_1 : [Int] = [] //至少定义为空
    var weightArray_1 : [Int] = [61,70,55]
    let weightArray_2 = [61,70,55]
    
    • 1
    • 2
    • 3

    添加修改

    weightArray_1[0] = 65 //[65,70,55]
    weightArray_1.append(45) //[65,70,55,45]
    weightArray_1 += [11,22] //[65,70,55,45,11,22]
    weightArray_1.insert(33, at:4) //[65,70,55,45,33,11,22]
    weightArray_1.remove(at: 1) //70 移除并返回值
    
    • 1
    • 2
    • 3
    • 4
    • 5

    数组函数

    weightArray_1.firstIndex(of: 55) //查询值的序列号
    weightArray_1.isEmpty //false
    weightArray_1.count
    weightArray_1.contains(55)
    weightArray_1.min()
    weightArray_1.sort()
    weightArray_1.shuffle()
    weightRecords.removeSubrange(3...7)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    生产数组
    .map 对数组中所有的数值依次进行指定的运算生产新数组
    .filter 对数组中所有的数值依次进行筛选生产新数字

    let goal = 50
    let result = weightArray_1.map { $0 - goal } //所有数值-50
    let result = weightArray_1.filter { $0 > goal } //大于50
    
    • 1
    • 2
    • 3
    let menu = [["apple"],["milk"]]
    
    • 1

    数组遍历

    for car in cars {
    
    }
    
    • 1
    • 2
    • 3

    字典

    括号中多个:代表定义字典

    student : [String: Int] = [:]
    student = ["Tom" : 20, "Bob" : 18]
    student["Tom"] = nil //删除
    
    • 1
    • 2
    • 3

    字典与数组混用

    let dailyMenu = [
    	"早餐":["面包","牛奶"],
    	"午餐":["面","饭"]
    ]
    
    • 1
    • 2
    • 3
    • 4

    循环

    for _ in 1...5 {
    	print("Hello")	
    }
    
    • 1
    • 2
    • 3
    repeat {
    
    } while Condition
    
    • 1
    • 2
    • 3

    闭包

    func compare(first: Int, second: Int) ->Bool {
        return first < second
    }
    //闭包完整写法
    let closure = { (first: Int, second: Int) -> Bool in
        return first < second
    }
    //闭包使用
    var number = [2, 18, 0, -9, 30]
    number.sort(by: closure)
    //双击throws自动出现
    number.sort(by: { (first: Int, second: Int) -> Bool in
        return first < second
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    几种精简写法

    //尾部闭包法 Trailing Code
    //省略函数括号直接使用{}
    number.sort { (first: Int, second: Int) -> Bool in
        return first < second
    }
    //省略数据类型,和返回类型,因sort函数已规定好闭包的形式
    number.sort { (first, second) in
        return first < second
    }
    //省略括号和return
    number.sort { first, second in first < second }
    //短参数
    number.sort { $0 < $1 }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    可选项参数 Optional

    考虑到用户的注册途径不同,可能使用第三方入口登陆,系统中可能存,或没存这个用户的用户名

    var username: String? = "小王"
    
    • 1

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mh4SySnJ-1660480762153)(https://cdn.jsdelivr.net/gh/Unitary-orz/unitary_oss/img/2022/08/20220814203637.png)]

    强行读取 Force Unwrap

    假设变量一定存在,并将结果转化为相应的数据类型,无法将nil读取

    print(username!)
    
    • 1

    判断后读取
    先判断是否为nil,再读取

    if username != nil{
        let checkUsername = username!
        print(checkUsername)
    }
    if let checkUsername = username {
        print(checkUsername) //局部变量
    }
    
    guard let checkUsername = usernaem {
    	print(checkUsername)
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    guard let 突破局部变量,必须有返回值或其他终止

    func guarDemo(){
        guard let safeUsername = username else {
            print("is nil")
            return
        }
        print(safeUsername)
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    本质是一个枚举型

    var policyNote: String?
    
    policyNote = nil
    policyNote = Optional.none
    
    • 1
    • 2
    • 3
    • 4

    结构

    struct Player {
        var name: String
        let initHealth = 100
    }
    
    • 1
    • 2
    • 3
    • 4

    mutating 若方法函数需要更改属性的数值,则需要在方法的关键词 func 前加上另一个关键词可变更

    struct Player {
    	mutating func damaged(by health: Int) {
    	
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    lazy懒,忽略掉初始化,初始化过后再执行代码

    调用此变量的函数都需要加上mutating

    let maxHealth = 100
    lazy var currentHealth = maxHealth
    
    • 1
    • 2

    属性观察器 Property Observer

    willSet 指的是检测到该属性将要发生变化,新的值以 newValue表示
    didSet 属性变化后运行,被改变的值以oldValue

    var livesRemaining = 5 {
    	willSet {
    		print("警告:还剩下\(newValue)条命")
    	}
    	didSet {
    		if liveRemaining != 0 {
    			print("已满血复活")
    		}
    		else {
    			print("游戏结束")
    		}
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    预计算属性 Computed Property

    • get 负责读取预计算属性的值, 只包含 get 中的内容时,关键词 get 可以省略
    • set 则代表赋值
    var isPalerOutOfLives: Bool{
    	get {
    		liveRemaining == 0 ? true : false
    	}//判断生命是否为0,并返回到newValue
    	set {
    		if newValue {
    			liveRemaining = 0
    		}
    	}
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    初始化器 Initializers

    默认初始化未设置值的属性

    init(name: String){
        self.name = name
    }
    
    init(name: String, currentHealth: Int, liveNumber: Int){
        self.name = name
        self.currentHealth = currentHealth
        self.liveNumber = liveNumber
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    类型属性 Type Property

    静态属性,以Type名为前缀调用,Type.xxxx``Type.xxx()

    static var count = 0
    
    init(name: String){
        self.name = name
        Player.count += 1
    }
    
    static func palyerNumber(){
        print("现在的玩家数量为\(count)")
    }
    
    var playerLiu = Player(name: "Liu")
    var playerWang = Player(name: "Wang")
    Player.palyerNumber() //2
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    不是静态的为实体属性 Instance Property,

    枚举 Enumeration

    enum EnergySource {
        case electricity
        case diesel
        case gasoline
    }
    var selectEnergy = EnergySource.electricity
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    和switch配套

    var selectEnergy = EnergySource.electricity
    var policyNote: String?
    
    switch selectEnergy {
    case .electricity:
        policyNote = "电动车"
    case .diesel:
        policyNote = "柴油车"
    case .gasoline:
        policyNote = "汽油车"
    }
    
    print(policyNote ?? "暂无说明")
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    class 必须写明初始化器,而 struct 自带默认的初始化器。

    class Car {
        var brand: String
            
        init(brand: String) {
            self.brand = brand
        }
        
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    继承

    • 子类: 父类 继承父类
    • override 重载父类
    • super.init() 调用父类
    class Seden: Car {
        override init(brand: String, year: Int, energy:EnergySource) {
            super.init(brand: brand, year: year, energy: energy)
            assistantEquipped = false
        }
    
    	func upgrade() {
    		
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    子类数组,储存在数组子类自动升级为父类

    var teslaModel3 = Seden(brand: "Tesla", year: 2017, energy: .electricity)
    var toyotaHilux = Track(brand: "Toyota", year: 1968, energy: .gasoline )
    
    let cars = [teslaModel3, toyotaHilux] //子类变成父类类型
    
    • 1
    • 2
    • 3
    • 4

    is 判断类型
    as? 判断并改变类型

     if car is Seden {
     	print("一辆轿车")
    }
    
    //转回为子类类型,调用Seden的方法,升级配置
    for car in cars {
        if let teslaModel3 = car as? Seden {
            teslaModel3.upgrade()
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    扩展 Extension

    extension 对类型进行扩展扩展支持以下四种类型: 结构 struct、类 class 、枚举 enum以及 protocol

    extension Car {
        var quickInfo: String {
    		//省略了get
            "The cat brand is \(brand), first built on \(year)"
        }
    }
    print(teslaModel3.quickInfo)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    类和结构

    适用于反复使用的框架一般定义为class
    不适合反复使用的实体和不需要继承常被定义为 struct

    Apple 官方文档的建议是当需要创建一个新的自定义类别时,可以先将其定义为 struct。只有你需要用到 class 继承的特性,或者是作为引用类型的特性时,再将其关键词换为 class

    typealia 类型别名

    typealias PhoneBook = [String: Int]
    let phoneBook: PhoneBook = ["王": 123456]
    
    • 1
    • 2

    协议 Protocol

    类似Java中的接口

    protocol Expressible {
    	var name: String { get }
    
    	init(name: String)
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    属性:

    • 需统一使用关键词 var
    • { get } 实体只读
    • { get set } 可以被实体读取或更改

    方法:不写具体方法,只定义

    结构 struct、类 class 和枚举 enum可使用protocol

    //结构可省略初始化
    struct User {
    	var name: String
    }
    
    • 1
    • 2
    • 3
    • 4

    可等性 Equatable

    自定义类型的等于判断所需要的protocol

    Static Methodstatic func == (Self, Self) -> Bool
    • 1
    struct Todo : Equatable {
    	var content: String
    
    	static func ==(lhs: Todo, rhs:Todo) -> Book {
    		return lhs.content == rhs.content
    	}
    }
    let todoOne = Todo(content:"Play game")
    let todoTwo = Todo(content:"Write Artcle")
    if (todoOne == todoTwo) {
    	print("Woo~")
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    只涉及基本类型可省略

    struct Todo : Equatable {
    	var content: String
    }
    
    • 1
    • 2
    • 3

    可比性 Comparable

    自定义类型的大小判断所需要的protocol

    static func < (lhs: Self, rhs: Self) -> Bool
    
    • 1
    struct Date {
        let year: Int
        let month: Int
        let day: Int
    }
    extension Date: Comparable {
        static func < (lhs: Date, rhs: Date) -> Bool {
            if lhs.year != rhs.year {
                return lhs.year < rhs.year //返回year Int 的比较结果
            }
            else if lhs.month != rhs.month {
                return lhs.month < rhs.month
            }
            else {
                return lhs.day < rhs.day
            }
        }
    }
    let date1 = Date(year: 1999, month: 07, day: 23)
    let date2 = Date(year: 2000, month: 11, day: 29)
    if date1 < date2 {
        print("date1 older")
    }
    else {
        print("data2 older")
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    可哈希性 Hashable

    产生一个随机、不可重复、独特的值,可以满足字典的Key属性,即把同一个类的不同对象当作一个唯一的hash值

    struct Name: Hashable {}
    // 生成两个对象放入字典,无Hash性会报错,会把同一个类的对象当作同一个字典key
    let todos [dayOne: todoOne, datTwo: todoTwo]
    
    • 1
    • 2
    • 3

    可辨识性 Identifiable

    自定义一个标示值,需要添加一个id 值,SwiftUI 会根据这个独特的 id 来判断视图的复用

    struct Name: Equatable, Identifiable, Codable{
        var id = UUID()
    
    • 1
    • 2

    可编码性

    当代码需要被转化成可以永久存储的信息时,需经过Encode

    let todoOne = Todo(content:"test")
    /* 可被编码为数据
    {
    	"content": "玩游戏",
    	"id": "274Dxxxxxx"
    */
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    异常处理

    fatalErrot() 抛出严重的错误
    throws 函数定义时,返回类型之前加上关键词
    do-try-catch 覆盖的代码段,会出现报错的代码,捕捉异常

    //枚举创建一种错误
    enum PasswordError: Error {
        case notLongEnoungh
    }
    
    func validPasswrod(_ password: String) throws -> Bool {
        if password.count < 6 {
            throw PasswordError.notLongEnoungh
        }
        return true
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    try? 后面接上可能抛出异常的函数,为可选类型(异常为nil,正常函数返回值)

    if let result = try? validPasswrod(passwd) {
        print("valid \(result)")
    } else {
        print("invalid")
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    try! 若异常则中断程序,等同于fatalError()

    CPU

    GCD 的全称是 Grand Central Dispatch,中央调度系统,其任务便是将代码自动在恰当的时机分配给 CPU 中的不同核心来处理,我们所写的所有代码都会被 GCD 运行在「主队列 main」中。其使用方法是 ​DispatchQueue.main.async {}​

    并发运行 Concurrent,它指的是在你的明确指示下,让复杂任务到别的窗口运行,不要卡在主队伍中,默认提供的并发队列叫做全局队列 Globa

    Quality of Service,简称** QOS** 负责告知全局队列中任务优先级的参数

    • .userInteractive UI
    • .userInitiated 用户发起的任务
    • .utility 杂项
    • .background 后台
    DispatchQueue.gobal(qos: .backgroud).async {
    	
    }
    
    • 1
    • 2
    • 3
  • 相关阅读:
    JUC并发编程——线程池学习:基础概念及三大方法、七大参数、四大拒绝策略(基于狂神说的学习笔记)
    算法金 | 再见!!!梯度下降(多图)
    BERT:来自 Transformers 的双向编码器表示 – 释放深度上下文化词嵌入的力量
    vue-element学习(一)
    easy-poi实现动态列(标题)、多sheet导出excel
    php-fpm基本配置
    太绝了!这份Python爬虫入门『最强教程』当之无愧
    Cadence Allegro DXF结构图的导入详细教程
    项目流程管理效率提升的3个核心点
    使用FileZilla连接本地和服务器进行文件传输
  • 原文地址:https://blog.csdn.net/qq_41725312/article/details/126335987