一、Swift 在 iOS 開發中的核心優勢
二、iOS 開發中 Swift 的高頻核心場景(附最佳實踐)
1. 可選值(Optional)處理(iOS 開發避崩核心)
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 臃腫)
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 中的正確使用(避免循環引用)
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 數據模型最佳選擇)
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 網絡請求(統一錯誤處理)
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 "網絡請求失敗"
}
}
}