1

swift 开发备忘

 1 year ago
source link: https://blog.kelu.org/tech/2022/12/07/swift-develop-remark.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
swift.jpg

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

官方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的自定义标签。

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


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK