Swift中的知识点总结

1、属性只想让外界访问,而不想让他们修改

// 属性只想让外界访问,而不想让他们修改,此时需要 public private(set) var name

csharp 复制代码
public private(set) var name: String

2、智能排序localizedStandardCompare的用法

比较带有数字的字符串时,可以考虑使用localizedStandardCompare,避免挨个字符比较

swift 复制代码
/*--------------- 智能排序localizedStandardCompare的用法 -------------------*/
// 比较带有数字的字符串时,可以考虑使用localizedStandardCompare,避免挨个字符比较
let fileNames = [
    "File 100.txt",
    "File 5.txt",
    "File 20.txt"
]
​
// (1) 数组排序
let resultArr = fileNames.sorted {
    $0.localizedStandardCompare($1) == .orderedAscending
}
print(resultArr)
​
// (2) 排序
let string1 = "File2.txt"
let string2 = "File10.txt"
let res = string1.localizedStandardCompare(string2)
switch res {
case .orderedAscending:
    print("(string1) 在 (string2) 之前")
case .orderedDescending:
    print("(string1) 在 (string2) 之后")
case .orderedSame:
    print("(string1) 在 (string2) 相同")
}
​
//(3)自定义类型
let fileItem = [
    FileItem(name: "File2.txt", size: 100),
    FileItem(name: "File10.txt", size: 200),
    FileItem(name: "File1.txt", size: 50)
]
let sortedItem = fileItem.sorted()
print(sortedItem)
​
struct FileItem: Comparable {
    let name: String
    let size: Int
    
    static func < (lhs: FileItem, rhs: FileItem) -> Bool {
        return lhs.name.localizedStandardCompare(rhs.name) == .orderedAscending
    }
}
​
// 文件管理
class FileManagerViewModel: ObservableObject {
    @Published var files: [String] = []
    func loadFiles() {
        let fileManager = FileManager.default
        let documentsURL = fileManager.urls(for: .documentDirectory, in: .userDomainMask).first!
        
        do {
            let allFiles = try fileManager.contentsOfDirectory(atPath: documentsURL.path)
            
            // 智能排序
            files = allFiles.sorted {
                $0.localizedStandardCompare($1) == .orderedAscending
            }
            
        } catch {
            
        }
    }
}

3、能用guard的地方尽量使用guard,不要使用if let绑定语法

过多的if let会造成代码缩进,形成类似地狱式回调的代码。同时也影响了可读性,会很难匹配哪个else对应哪个if 可以多使用guard语法,guard会将变量的作用域提升到top level,从而提升可读性,也能使逻辑处理更清晰

javascript 复制代码
​
func guardDemo(name: String) {
    guard let captureDevice = AVCaptureDevice.default(for: .video) else {
        return
    }
    // 自动白平衡
    if captureDevice.isWhiteBalanceModeSupported(.continuousAutoWhiteBalance) {
        do {
            try captureDevice.lockForConfiguration()
            captureDevice.whiteBalanceMode = .continuousAutoWhiteBalance
            captureDevice.unlockForConfiguration()
        } catch {
​
        }
    }
​
    // 自动对焦
    if captureDevice.isFocusModeSupported(.continuousAutoFocus) {
        do {
            try captureDevice.lockForConfiguration()
            captureDevice.focusMode = .continuousAutoFocus
            captureDevice.unlockForConfiguration()
        } catch {
​
        }
    }
​
​
    // 自动曝光
    if captureDevice.isExposureModeSupported(.continuousAutoExposure) {
        do {
            try captureDevice.lockForConfiguration()
            captureDevice.exposureMode = .continuousAutoExposure
            captureDevice.unlockForConfiguration()
        } catch {}
    }
}

4、Measurement和MeasurementFormatter的用法

Measurementswift中用于处理物理测量的强大类型,它结合了数值和单位,提供了类型安全、单位转换和国际化的支持

scss 复制代码
 // 1、创建带有单位的测量值
​
let distance = Measurement(value: 100, unit: UnitLength.meters)
​
let temperature = Measurement(value: 20, unit: UnitTemperature.celsius)
​
let speed = Measurement(value: 60, unit: UnitSpeed.kilometersPerHour)
​
// 2、长度单位
​
let length = Measurement(value: 30, unit: UnitLength.kilometers)
let miles = Measurement(value: 10, unit: UnitLength.miles)
​
let weitht = Measurement(value: 10, unit: UnitMass.kilograms)
​
 // 3、不同单位进行换算(自动换算)
​
let meters = Measurement(value: 1000, unit: UnitLength.meters)
​
let kilometers = Measurement(value: 1, unit: UnitLength.kilometers)
​
let totalLength = meters + kilometers // 2000.0m(kilometers自动转换为m)
​
// 4、使用MeasurementFormatter格式化显示
​
let formatter = MeasurementFormatter()
​
formatter.unitOptions = .providedUnit
​
formatter.unitStyle = .medium
​
let dis = Measurement(value: 5.2, unit: UnitLength.kilometers)
print(formatter.string(from: dis)) // 5.2km
​
 // 本地化显示
​
formatter.locale = Locale(identifier: "zh_CN")
​
print(formatter.string(from: dis)) // 5.2公里
​
 // 温度格式化
​
let tempFormatter = MeasurementFormatter()
​
tempFormatter.numberFormatter.maximumFractionDigits = 1
​
let temperae = Measurement(value: 23.5, unit: UnitTemperature.celsius)
​
print(formatter.string(from: temperae)) // 23.5°C
​

5、CollectionOfOne和CollectionDifference的用法

ColletionOfOne是一个只包含单个元素的集合类型,实现了Collection协议

CollectionDifference表示两个集合之间的差异

在Swift中,applyingCollectionDifference的一个方法,它用于将一个差异(difference)应用到集合上从而生成一个新的集合。这个方法通常用于更新一个数组(或其他集合)以反映另一个数组的状态,而不需要完全替换。

swift 复制代码
func applying(_ difference: CollectionDifference<Element>) -> [Element]?
​
let diffArr = newArray.difference(from: oldArray)
let allArr = oldArray.applying(diffArr)
scss 复制代码
/----- ColletionOfOne是一个只包含单个元素的集合类型,实现了Collection协议---------/
  let singleCollection = CollectionOfOne(88)
  print(singleCollection.first!) // 88
  print(singleCollection.count) // 1
​
  /---------CollectionDifference表示两个集合之间的差异-------------------------/
​
  let oldArray = ["A","B","C","D"]
  let newArray = ["A","C","D","E"];
​
  let diffArr = newArray.difference(from: oldArray)
  let allArr = oldArray.applying(diffArr)
  print("最终结果:(String(describing: allArr))") // 最终结果:Optional(["A", "C", "D", "E"])
  for change in diffArr {
    switch change {
    case .remove(let offset,let element,let associatedWith):
    // 移除:索引 1 处的元素 B associatedWith: -1
      print("移除:索引 (offset) 处的元素 (element) associatedWith: (associatedWith ?? -1)") 
    case .insert(let offset,let element,let associatedWith):
    // 插入:索引 3 处的元素 E associatedWith: -1
      print("插入:索引 (offset) 处的元素 (element) associatedWith: (associatedWith ?? -1)")
    }
  }
​
let oldItems = ["a", "b", "c", "d"]
let newItems = ["a", "c", "d", "e"]
let difference = newItems.difference(from: oldItems)
​
tableView.beginUpdates()
for change in difference {
    switch change {
    case .remove(let offset, _, _):
        tableView.deleteRows(at: [IndexPath(row: offset, section: 0)], with: .fade)
    case .insert(let offset, _, _):
        tableView.insertRows(at: [IndexPath(row: offset, section: 0)], with: .fade)
    }
}
tableView.endUpdates()

6、Swift 中的 #error 用法详解

#error是一个编译时指令,用于在编译过程中生成错误信息并停止编译

csharp 复制代码
// 强制要求条件
struct API {
    #error("请设置 API Key")
    static let apiKey = ""
}
​
// 检查配置
enum Environment {
    case development, production
    
    static var current: Environment {
        #error("请设置环境变量")
        return .development
    }
}
// 版本检查
#if swift(<5.0)
    #error("此项目需要 Swift 5.0 或更高版本")
#endif
​
// 框架开发中标记未实现功能
class MyFramework {
    func requiredMethod() {
        // 标记为必须实现的方法
        #error("子类必须重写此方法")
    }
}
​
class CustomImplementation: MyFramework {
    override func requiredMethod() {
        // 如果不实现,编译会报错
        print("实现自定义逻辑")
    }
}

#error与 fatalError()这两个都是用于强制停止程序执行,但工作在不同的阶段,有着本质区别:

核心区别总结

特性 #error fatalError()
执行阶段 编译时 运行时
位置 代码中任何地方 只能在函数/方法体内
可执行代码 不能包含 可以包含其他代码
条件检查 编译时条件(#if 运行时条件(if, guard
错误类型 编译错误 运行时错误
可捕获 否(但可以设置错误处理)
信息显示 编译错误信息 运行时崩溃信息

7、dump和print的区别

  • print: 用于输出一个或多个值到控制台,适合用于简单的调试和日志记录。print函数会添加换行符
  • dump: 主要用于输出对象的内部结构,包含其属性(包括私有属性)以及嵌套对象的结构。它会递归地输出一个对象的镜像,显示所有子成员。通常用于调试复杂的对象,比如数组、字典、自定义实例灯
相关推荐
2501_916007474 小时前
苹果手机iOS应用管理全指南与隐藏功能详解
android·ios·智能手机·小程序·uni-app·iphone·webview
代码不行的搬运工6 小时前
面向RDMA网络的Swift协议
开发语言·网络·swift
2501_915106326 小时前
全面理解 iOS 帧率,构建从渲染到系统行为的多工具协同流畅度分析体系
android·ios·小程序·https·uni-app·iphone·webview
TouchWorld8 小时前
iOS逆向-哔哩哔哩增加3倍速(1)-最大播放速度
ios·逆向
RollingPin8 小时前
React Native与Flutter的对比
android·flutter·react native·ios·js·移动端·跨平台开发
2501_916008898 小时前
iOS 能耗检测的工程化方法,构建多工具协同的电量分析与性能能效体系
android·ios·小程序·https·uni-app·iphone·webview
long_run9 小时前
Objective-C 类与对象详细入门
ios
美狐美颜SDK开放平台9 小时前
跨平台直播美颜SDK开发:iOS/Android/WebGL实现要点
android·人工智能·ios·美颜sdk·第三方美颜sdk·视频美颜sdk·美狐美颜sdk
2501_915921439 小时前
重新理解 iOS 的 Bundle Id 从创建、管理到协作的工程策略
android·ios·小程序·https·uni-app·iphone·webview