一、Swift 在 iOS 開發中的核心優勢

相比 Objective-C,Swift 適配 iOS 開發有這些不可替代的優勢:

  1. 類型安全:編譯期檢查類型錯誤,減少 iOS 運行時崩潰(如空指針、類型不匹配);
  2. 語法簡潔:用更少代碼實現 OC 同等功能(如可選鏈、閉包、擴展);
  3. 性能更優:原生支持值類型(結構體),避免 OC 的對象引用開銷,適配 iOS 設備的性能特性;
  4. 無縫兼容 OC:可直接調用 OC 框架(UIKit/Foundation),也能混編,遷移成本低;
  5. 現代特性:支持泛型、協議擴展、Result 類型等,適配 iOS 複雜業務場景。

二、iOS 開發中 Swift 的高頻核心場景(附最佳實踐)

1. 可選值(Optional)處理(iOS 開發避崩核心)

iOS 開發中大量場景會遇到空值(如網絡返回、控件初始化、數據解析),Swift 的可選值是避崩關鍵,推薦這些寫法:

swift

// 反例:強制解包(!)極易崩潰(iOS開發中嚴禁)
let labelText = UILabel().text! 

// 推薦寫法1:可選綁定(處理單個可選值)
if let text = UILabel().text {
    print("文本:\(text)")
} else {
    print("文本為空")
}

// 推薦寫法2:可選鏈+空合運算符(iOS最常用)
let userName = user?.nickname ?? "未知用户" // 空則用默認值
let avatarUrl = user?.profile?.avatar ?? "https://default.png"

// 推薦寫法3:guard let(提前退出,減少嵌套)
func setupUserInfo(_ user: User?) {
    guard let user = user, let name = user.name else {
        print("用户信息不全,退出配置")
        return
    }
    nameLabel.text = name // 後續無需再判空
}

2. 擴展(Extension)拆分 iOS 大類(解決 VC 臃腫)

iOS 開發中 ViewController/UIView 容易代碼冗餘,用 Extension 按功能拆分:

swift

// 原問題:UserVC上千行,包含UI配置、代理、網絡請求
// 優化:拆分為多個Extension
class UserVC: UIViewController {
    // 僅保留核心屬性
    let nameLabel = UILabel()
    let vm = UserVM()
}

// 1. UI配置邏輯
extension UserVC {
    func setupUI() {
        nameLabel.then {
            $0.font = .systemFont(ofSize: 16)
            $0.textColor = .black
            view.addSubview($0)
            // iOS 11+推薦AutoLayout寫法
            $0.translatesAutoresizingMaskIntoConstraints = false
            NSLayoutConstraint.activate([
                $0.centerXAnchor.constraint(equalTo: view.centerXAnchor),
                $0.topAnchor.constraint(equalTo: view.topAnchor, constant: 20)
            ])
        }
    }
}

// 2. 代理邏輯(如TableView代理)
extension UserVC: UITableViewDelegate, UITableViewDataSource {
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return vm.userList.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
        cell.textLabel?.text = vm.userList[indexPath.row].name
        return cell
    }
}

// 3. 網絡請求邏輯
extension UserVC {
    func fetchData() {
        vm.loadUser { [weak self] in
            DispatchQueue.main.async {
                self?.tableView.reloadData()
            }
        }
    }
}

3. 閉包(Closure)在 iOS 中的正確使用(避免循環引用)

iOS 開發中閉包(網絡請求、按鈕點擊、動畫回調)極易引發內存泄漏,核心是weak self

swift

// 反例:閉包捕獲self導致循環引用(VC無法釋放)
func loadData() {
    NetworkManager.fetch {
        self.nameLabel.text = "加載完成" // 強引用self
    }
}

// 推薦寫法1:[weak self] + guard let(最安全)
func loadData() {
    NetworkManager.fetch { [weak self] in
        guard let self = self else { return }
        self.nameLabel.text = "加載完成"
    }
}

// 推薦寫法2:[unowned self](確定self不會提前釋放時,如動畫回調)
UIView.animate(withDuration: 0.3) { [unowned self] in
    self.view.alpha = 1.0
}

4. 結構體(Struct)vs 類(Class)(iOS 數據模型最佳選擇)

iOS 開發中數據模型優先用結構體(值類型),避免類的引用開銷和內存問題:

swift

// 推薦:數據模型用結構體(值類型,線程安全,無內存泄漏)
struct UserModel: Codable {
    let id: String
    let name: String?
    let age: Int
    
    // 自定義解析規則(適配iOS接口字段不一致)
    enum CodingKeys: String, CodingKey {
        case id = "user_id" // 接口字段是user_id,模型用id
        case name
        case age = "user_age"
    }
}

// 類僅用於需要繼承/引用語義的場景(如ViewController、ViewModel)
class UserVM {
    var userList: [UserModel] = [] // 結構體數組
    func loadUser() { /* 網絡請求邏輯 */ }
}

5. Result 類型處理 iOS 網絡請求(統一錯誤處理)

iOS 網絡請求的成功 / 失敗回調,用 Swift 的Result類型替代多閉包,代碼更整潔:

swift

// 定義網絡請求函數(返回Result)
func fetchUser(id: String) async -> Result<UserModel, NetworkError> {
    guard let url = URL(string: "https://api.example.com/user/\(id)") else {
        return .failure(.invalidURL)
    }
    
    do {
        let (data, _) = try await URLSession.shared.data(from: url)
        let user = try JSONDecoder().decode(UserModel.self, from: data)
        return .success(user)
    } catch {
        return .failure(.parseError)
    }
}

// 使用(iOS 15+推薦async/await)
Task {
    let result = await fetchUser(id: "123")
    switch result {
    case .success(let user):
        print("用户:\(user.name ?? "未知")")
    case .failure(let error):
        print("錯誤:\(error.localizedDescription)")
    }
}

// 錯誤枚舉(適配iOS網絡場景)
enum NetworkError: LocalizedError {
    case invalidURL
    case parseError
    case networkError
    
    var errorDescription: String? {
        switch self {
        case .invalidURL: return "URL格式錯誤"
        case .parseError: return "數據解析失敗"
        case .networkError: return "網絡請求失敗"
        }
    }
}

三、iOS Swift 開發的避坑指南

  1. 避免強制解包(!):iOS 運行時任何空值都會導致崩潰,僅在 100% 確定非空時使用(幾乎不用);
  2. AutoLayout 適配:Swift 中禁用frame硬編碼(適配不同 iOS 設備尺寸),優先用 AutoLayout/UIKit 佈局 API;
  3. 內存管理:閉包必須處理weak self,尤其是 VC 中引用自身的閉包(如網絡請求、定時器);
  4. 版本適配:用if #available(iOS X.X, *)適配不同系統版本(如 iOS 15 的新 API);
  5. 混編注意:Swift 調用 OC 時,OC 的nil會轉為 Swift 的nil,OC 的NSArray會轉為[Any]?,需做好類型轉換。

總結

  1. 核心優勢:Swift 的類型安全、可選值、擴展是解決 iOS 開發崩潰、代碼臃腫的關鍵;
  2. 高頻實踐:可選值用 “可選鏈 + 空合運算符”、大類拆分為 Extension、閉包必加weak self、數據模型優先用結構體;
  3. 避坑重點:禁用強制解包、適配 iOS 版本、做好內存管理,確保代碼穩定且符合 Apple 審核規範。