面向初学者的 Swift 应用性能优化

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

引言:为什么性能从第一天起就很重要

当你开始用Swift编写代码时,很容易只关注功能性:"只要能用就行"。然而,经验丰富的开发者知道:性能优化不是最后的润色,而是从第一行代码就开始打下的基础。慢速的应用会流失用户、消耗电池并收到差评。

在本文中,我们将分析优化iOS和macOS的Swift应用的关键方面。你将了解如何避免新手常见错误,学会处理内存、线程和性能分析。每个部分都包含实用的代码示例,你可以立即应用到自己的项目中。

1. 内存管理:ARC与避免循环引用

Swift使用自动引用计数(ARC)来管理内存。这意味着当对象不再有强引用时,它们会被释放。但如果你创建了循环引用,内存将永远不会被释放——就会发生内存泄漏。

弱引用和无主引用

使用weak和unowned来打破循环。这通常在闭包和委托中需要用到。

class ViewController: UIViewController {
    var networkManager: NetworkManager?
    
    func fetchData() {
        networkManager?.fetch { [weak self] result in
            guard let self = self else { return }
            // 处理结果
            self.updateUI(with: result)
        }
    }
}

何时使用:

  • weak — 如果引用可能变为nil(例如委托)。
  • unowned — 如果你确定对象的生命周期比闭包长(例如父控制器)。

避免不必要的拷贝

值类型(结构体、枚举)在赋值时会被拷贝。对于大数据,使用class或通过inout传递引用。

// 不好:拷贝大数组
func processLargeArray(_ array: [Int]) {
    // array — 是副本
}

// 好:通过引用传递
func processLargeArray(_ array: inout [Int]) {
    // array — 是对原数组的引用
}

2. 多线程处理:GCD和async/await

iOS和macOS是多线程系统。如果你在主线程上执行繁重操作(数据加载、图像处理),界面会"卡死"。使用Grand Central Dispatch(GCD)或现代的async/await。

GCD:基础模式

DispatchQueue.global(qos: .userInitiated).async {
    // 在后台执行繁重工作
    let result = performHeavyCalculation()
    
    DispatchQueue.main.async {
        // 在主线程更新UI
        self.label.text = "\(result)"
    }
}

服务质量(QoS):

  • .userInteractive — 用于UI(几乎即时)。
  • .userInitiated — 用于用户操作(几秒内)。
  • .utility — 用于长时间任务(进度条)。
  • .background — 用于后台同步(不紧急)。

Async/await(Swift 5.5+)

更易读的异步处理方式:

func fetchImage(from url: URL) async throws -> UIImage {
    let (data, _) = try await URLSession.shared.data(from: url)
    guard let image = UIImage(data: data) else {
        throw URLError(.badServerResponse)
    }
    return image
}

// 在Task中调用
Task {
    do {
        let image = try await fetchImage(from: url)
        self.imageView.image = image
    } catch {
        print("加载错误:\(er                

博客

书籍推荐