Swift 学习笔记

  • Post author:
  • Post category:其他




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



版权声明:本文为qq_41725312原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。