Swift 学习笔记

这篇博客详细记录了Swift的学习笔记,包括基本语法如注释、运算符、函数、数组、字典和循环;深入讲解了闭包、可选项参数、结构、枚举、类以及协议等概念;还涵盖了异常处理、CPU调度(GCD)和iOS开发中的其他重要知识点。
摘要由CSDN通过智能技术生成

Swift 学习笔记

iOS开发学习中的简单记录

Swift基本语法

注释

//
/*
多行注释
*/

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

let name1//常量
var name2//变量

运算符

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

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

**字符串插值 String Interpolation **

省略+

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

函数

定义及使用

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

func sayHi(){
	print("Hi")
}
func sayHi(name: String){
	print("Hi\(name)")
}
sayHi(name: "Liu")

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

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

//不要参数标签
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"))

函数重载 Function Overload

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

func driveForward() {
    print("move.....")
}
func driveForward(meters: Int) {
    print("move.....\(meters)")
}
driveForward() //move.....
driveForward(meters: 10) //move.....10

函数返回值

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

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

函数的格式

在这里插入图片描述

数组

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

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

添加修改

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 移除并返回值

数组函数

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)

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

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

数组遍历

for car in cars {

}

字典

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

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

字典与数组混用

let dailyMenu = [
	"早餐":["面包","牛奶"],
	"午餐":["面","饭"]
]

循环

for _ in 1...5 {
	print("Hello")	
}
repeat {

} while Condition

闭包

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
})

几种精简写法

//尾部闭包法 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 }

可选项参数 Optional

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

var username: String? = "小王"

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

强行读取 Force Unwrap

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

print(username!)

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

if username != nil{
    let checkUsername = username!
    print(checkUsername)
}
if let checkUsername = username {
    print(checkUsername) //局部变量
}

guard let checkUsername = usernaem {
	print(checkUsername)
}

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

func guarDemo(){
    guard let safeUsername = username else {
        print("is nil")
        return
    }
    print(safeUsername)
}

本质是一个枚举型

var policyNote: String?

policyNote = nil
policyNote = Optional.none

结构

struct Player {
    var name: String
    let initHealth = 100
}

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

struct Player {
	mutating func damaged(by health: Int) {
	
	}
}

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

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

let maxHealth = 100
lazy var currentHealth = maxHealth

属性观察器 Property Observer

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

var livesRemaining = 5 {
	willSet {
		print("警告:还剩下\(newValue)条命")
	}
	didSet {
		if liveRemaining != 0 {
			print("已满血复活")
		}
		else {
			print("游戏结束")
		}
	}
}

预计算属性 Computed Property

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

初始化器 Initializers

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

init(name: String){
    self.name = name
}

init(name: String, currentHealth: Int, liveNumber: Int){
    self.name = name
    self.currentHealth = currentHealth
    self.liveNumber = liveNumber
}

类型属性 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

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

枚举 Enumeration

enum EnergySource {
    case electricity
    case diesel
    case gasoline
}
var selectEnergy = EnergySource.electricity

和switch配套

var selectEnergy = EnergySource.electricity
var policyNote: String?

switch selectEnergy {
case .electricity:
    policyNote = "电动车"
case .diesel:
    policyNote = "柴油车"
case .gasoline:
    policyNote = "汽油车"
}

print(policyNote ?? "暂无说明")

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

class Car {
    var brand: String
        
    init(brand: String) {
        self.brand = brand
    }
    
}

继承

  • 子类: 父类 继承父类
  • 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() {
		
	}
}

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

var teslaModel3 = Seden(brand: "Tesla", year: 2017, energy: .electricity)
var toyotaHilux = Track(brand: "Toyota", year: 1968, energy: .gasoline )

let cars = [teslaModel3, toyotaHilux] //子类变成父类类型

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

 if car is Seden {
 	print("一辆轿车")
}

//转回为子类类型,调用Seden的方法,升级配置
for car in cars {
    if let teslaModel3 = car as? Seden {
        teslaModel3.upgrade()
    }
}

扩展 Extension

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

extension Car {
    var quickInfo: String {
		//省略了get
        "The cat brand is \(brand), first built on \(year)"
    }
}
print(teslaModel3.quickInfo)

类和结构

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

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

typealia 类型别名

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

协议 Protocol

类似Java中的接口

protocol Expressible {
	var name: String { get }

	init(name: String)
}

属性:

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

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

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

//结构可省略初始化
struct User {
	var name: String
}

可等性 Equatable

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

Static Methodstatic func == (Self, Self) -> Bool
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~")
}

只涉及基本类型可省略

struct Todo : Equatable {
	var content: String
}

可比性 Comparable

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

static func < (lhs: Self, rhs: Self) -> Bool
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")
}

可哈希性 Hashable

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

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

可辨识性 Identifiable

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

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

可编码性

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

let todoOne = Todo(content:"test")
/* 可被编码为数据
{
	"content": "玩游戏",
	"id": "274Dxxxxxx"
*/

异常处理

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
}

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

if let result = try? validPasswrod(passwd) {
    print("valid \(result)")
} else {
    print("invalid")
}

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
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值