swift 开发备忘

做个简单备忘。以后还得继续练习补充。

官方reference:https://developer.apple.com/cn/documentation/swift/

一、playground

image-20221208午後40856523

image-20221208午後40905540

二、速查表

https://swiftgg.gitbook.io/swift/huan-ying-shi-yong-swift

image-20221208午後45745558

let bmi = wight / (height * height)
bmiValue = String(format: "%.1f", bmi)

三、数据类型

  • 基础数据类型

    • Int 表示整型值;

    • UInt 无符号类型;

    • DoubleFloat 表示浮点型值;

    • 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
        
      • 也可以在声明可选变量时使用感叹号(!)替换问号(?)。这样可选变量在使用时就不需要再加一个感叹号(!)来获取值,它会自动解析。

      image-20221222午後40013406

      方法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中的闭包有很多优化的地方:

  1. 根据上下文推断参数和返回值类型
  2. 从单行表达式闭包中隐式返回(也就是闭包体只有一行代码,可以省略return)
  3. 可以使用简化参数名,如$0, $1(从0开始,表示第i个参数…)
  4. 提供了尾随闭包语法(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)
    
    1. 尾随闭包是一个书写在函数括号之后的闭包表达式,函数支持将其作为最后一个参数调用。

    2. func someFunctionThatTakesAClosure(closure: () -> Void) {
          // 函数体部分
      }
           
      // 以下是不使用尾随闭包进行函数调用
      someFunctionThatTakesAClosure({
          // 闭包主体部分
      })
           
      // 以下是使用尾随闭包进行函数调用
      someFunctionThatTakesAClosure() {
        // 闭包主体部分
      }
      
    3. image-20221221午後55652630

    4. import Cocoa
           
      let names = ["AT", "AE", "D", "S", "BE"]
           
      //尾随闭包
      var reversed = names.sorted() { $0 > $1 }
      print(reversed)
           
      // ["S", "D", "BE", "AT", "AE"]
      
    5. sort() 后的 { $0 > $1} 为尾随闭包。

    6. 注意: 如果函数只需要闭包表达式一个参数,使用尾随闭包时,可以把()省略掉。

      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

image-20221221午後55652630

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和依赖管理

https://cocoapods.org/

sudo gem install cocoapods

image-20221228午後64838262

拉数据。

pod setup --verbose

image-20221228午後65525857

pod init
pod install

image-20221228午後70141885

九、SwiftUI

2019 WWDC发布。

很多灵感来自网页设计。

元素堆叠的感觉,让我想起了前端vue的自定义标签。

看来多学一点框架也不是坏事,可以互通各自的设计理念。搞的我有点想看一下另一个前端框架了。

参考资料


iOS 开发环境配置备忘 遵守互联标准 打破生僻字困局 — 招商银行