swift 开发备忘
2022-12-07 tech mac swift ios apple-developer xcode 17 mins 9 图 6281 字
做个简单备忘。以后还得继续练习补充。
官方reference:https://developer.apple.com/cn/documentation/swift/
一、playground
二、速查表
https://swiftgg.gitbook.io/swift/huan-ying-shi-yong-swift
let bmi = wight / (height * height)
bmiValue = String(format: "%.1f", bmi)
三、数据类型
-
基础数据类型
-
Int
表示整型值; -
UInt
无符号类型; -
Double
和Float
表示浮点型值; -
Bool
是布尔型值; -
String
是文本型数据。var stringA = "Hello, World!" let stringB = String("kelu.org") var stringC = stringA + stringB // 字符串长度使用 String.count 属性来计算 stringC.count
相关函数:
- isEmpty
- hasPrefix(prefix: String)
- hasSuffix(suffix: String)
- Int(String)
- String.count
- utf8
- utf16
- unicodeScalars
-
Character 字符。
-
nil
空。 -
可选类型 optional
-
如果一个可选类型的实例包含一个值,可以用后缀操作符 !来访问这个值(强制解析),但去获取值为nil的可选变量会有运行时错误。
var optionalInteger: Int? var optionalInteger: Optional<Int> var username:<data type> = <optional initial value> var username: String? = nil
-
也可以在声明可选变量时使用感叹号(!)替换问号(?)。这样可选变量在使用时就不需要再加一个感叹号(!)来获取值,它会自动解析。
方法4相当于三元操作符
?:
。我比较喜欢这种方式。 -
-
类型别名
对当前的类型定义了另一个名字,类型别名通过使用 typealias 关键字来定义。语法格式如下:
typealias newname = type
-
-
类型安全
在编译代码时进行类型检查(type checks),并把不匹配的类型标记为错误。
-
类型推断
没有显式指定类型,Swift 会使用类型推断(type inference)来选择合适的类型。
-
变量
var variableName = <initial value>
-
常量
let constantName = <initial value> let constB:Float = 3.14159 // 3.14159 为字面量 let constantName:<data type> = <optional initial value>
字面量是指由字母,数字等构成的字符串或者数值,它只能作为右值出现。
-
数组
Array
var someInts = [Int](repeating: 0, count: 3) var someInts:[Int] = [10, 20, 30]
-
字典
Dictionary
var someDict:[Int:String] = [1:"One", 2:"Two", 3:"Three"] var removedValue = someDict.removeValue(forKey: 2) for (key, value) in someDict { print("字典 key \(key) - 字典 value \(value)") } for (key, value) in someDict.enumerated() { print("字典 key \(key) - 字典 (key, value) 对 \(value)") } // 转数组 let dictKeys = [Int](someDict.keys) let dictValues = [String](someDict.values)
-
错误处理
func makeASandwich() throws { // ... } do { try makeASandwich() eatASandwich() } catch SandwichError.outOfCleanDishes { washDishes() } catch SandwichError.missingIngredients(let ingredients) { buyGroceries(ingredients) }
-
枚举
// 定义枚举 enum DaysofaWeek { case Sunday case Monday case TUESDAY case WEDNESDAY case THURSDAY case FRIDAY case Saturday }
四、闭包
Swift中的闭包有很多优化的地方:
- 根据上下文推断参数和返回值类型
- 从单行表达式闭包中隐式返回(也就是闭包体只有一行代码,可以省略return)
- 可以使用简化参数名,如$0, $1(从0开始,表示第i个参数…)
- 提供了尾随闭包语法(Trailing closure syntax)
{(parameters) -> return type in
statements
}
{(Int, Int) -> Bool in
Statement1
Statement 2
---
Statement n
}
-
闭包表达式
排序完成后,sorted(by:) 方法会返回一个与原数组大小相同,包含同类型元素且元素已正确排序的新数组。原数组不会被 sorted(by:) 方法修改。
import Cocoa let names = ["AT", "AE", "D", "S", "BE"] // 使用普通函数(或内嵌函数)提供排序功能,闭包函数类型需为(String, String) -> Bool。 func backwards(s1: String, s2: String) -> Bool { return s1 > s2 } var reversed = names.sorted(by: backwards) print(reversed) // ["S", "D", "BE", "AT", "AE"]
参数名称缩写,$0,$1,$2
import Cocoa let names = ["AT", "AE", "D", "S", "BE"] var reversed = names.sorted( by: { $0 > $1 } ) print(reversed)
运算符函数
import Cocoa let names = ["AT", "AE", "D", "S", "BE"] var reversed = names.sorted(by: >) print(reversed)
-
尾随闭包是一个书写在函数括号之后的闭包表达式,函数支持将其作为最后一个参数调用。
-
func someFunctionThatTakesAClosure(closure: () -> Void) { // 函数体部分 } // 以下是不使用尾随闭包进行函数调用 someFunctionThatTakesAClosure({ // 闭包主体部分 }) // 以下是使用尾随闭包进行函数调用 someFunctionThatTakesAClosure() { // 闭包主体部分 }
-
import Cocoa let names = ["AT", "AE", "D", "S", "BE"] //尾随闭包 var reversed = names.sorted() { $0 > $1 } print(reversed) // ["S", "D", "BE", "AT", "AE"]
-
sort() 后的 { $0 > $1} 为尾随闭包。
-
注意: 如果函数只需要闭包表达式一个参数,使用尾随闭包时,可以把
()
省略掉。reversed = names.sorted { $0 > $1 }
-
五、数据结构
struct
struct MarksStruct {
var mark: Int
init(mark: Int) {
self.mark = mark
}
}
var aStruct = MarksStruct(mark: 98)
var bStruct = aStruct // aStruct 和 bStruct 是使用相同值的结构体!
bStruct.mark = 97
print(aStruct.mark) // 98
print(bStruct.mark) // 97
class
class SomeClass: SomeSuperclass {
// 类的定义
}
Class 必须提供init函数,struct 不需要提供。
class 是引用传递,所以直接let class1 = class2
,对class1进行操作,class2取出来也会变化,因为是同一个class。
struct 是值传递,所以 let struct1 = struct2
,得到的是两个不同的struct。
Struct 是immutable
的,方法要修改struct
的值必须声明mutating
。
从父类强制指定子 class: as!
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Get the new view controller using segue.destination.
// Pass the selected object to the new view controller.
if segue.identifier == "testSeg" {
let destinationVC = segue.destination as! ResultViewController
destinationVC.bmiValue = calculatorBrain.getBMIValue()
destinationVC.advice = calculatorBrain.getAdvice()
destinationVC.color = calculatorBrain.getColor()
}
}
Closures 闭包
https://docs.swift.org/swift-book/LanguageGuide/Closures.html
如果函数最后一个参数是闭包,可以直接扔在最后,叫尾随闭包。
六、delegate 和 protocol
protocol 就是一种简易灵活的继承方式。
delegate 设计模式。(有点像用类继承的方式封装的观察者模式/事件模式。普通的事件模式你需要监听事件和传输内容,在delegate中你只需在controller中写明某个组件的delegate为self,即可在controller中直接使用对应的事件方法。)
七、extension
扩展就是向一个已有的类、结构体或枚举类型添加新功能。扩展可以对一个类型添加新的功能,但是不能重写已有的功能:
- 添加计算型属性和计算型静态属性
- 定义实例方法和类型方法
- 提供新的构造器
- 定义下标
- 定义和使用新的嵌套类型
- 使一个已有类型符合某个协议
extension SomeType: SomeProtocol, AnotherProctocol {
// 协议实现写到这里
}
八、第三方库 cocoapods和依赖管理
sudo gem install cocoapods
拉数据。
pod setup --verbose
pod init
pod install
九、SwiftUI
2019 WWDC发布。
很多灵感来自网页设计。
元素堆叠的感觉,让我想起了前端vue的自定义标签。
看来多学一点框架也不是坏事,可以互通各自的设计理念。搞的我有点想看一下另一个前端框架了。