iOS 知识积累第一弹:从 struct 到 APP 生命周期的全景复盘

struct vs class:值类型与引用类型的"江湖地位"

swift 复制代码
// 值类型:struct
struct Point {
    var x: Int
    var y: Int
}
var p1 = Point(x: 0, y: 0)
var p2 = p1          // 复制一份全新内存
p2.x = 10
print(p1.x) // 0  ✅ 原值不动

// 引用类型:class
class Button {
    var title: String = "OK"
}
let btn1 = Button()
let btn2 = btn1      // 指向同一块堆内存
btn2.title = "Cancel"
print(btn1.title) // Cancel ❗️共享修改

结论

  • 需要"拷贝"语义 → struct(线程安全、写时复制)
  • 需要"共享"或继承 → class

iOS 应用生命周期

iOS 13 之后分两块:

  • AppDelegate:进程级事件(启动、终止、后台下载)
  • SceneDelegate:窗口级事件(多窗口支持)
swift 复制代码
// AppDelegate.swift
func application(_ application: UIApplication,
                 didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    // 初始化 SDK、注册推送
    return true
}

// SceneDelegate.swift
func sceneDidBecomeActive(_ scene: UIScene) {
    // 刷新 UI、重启定时器
}

记忆口诀:Launch → Foreground → Active → Background → Suspended → Terminate

strong / weak / unowned

修饰符 是否增加引用计数 是否可选 场景
strong 默认所有权
weak delegate、父→子
unowned 生命周期同步(如闭包捕获 self)

循环引用实战

swift 复制代码
class Person {
    var pet: Pet?
    deinit { print("Person 释放") }
}
class Pet {
    // 错误:strong 互相持有
    // var owner: Person?
    // 正确:
    weak var owner: Person?
    deinit { print("Pet 释放") }
}

闭包场景:

swift 复制代码
class Net {
    var completion: (() -> Void)?
    func load() {
        // 捕获列表破局
        completion = { [weak self] in
            self?.updateUI()
        }
    }
}

口诀:双向强引用 = 死锁;weak / unowned 拆链

MVC → MVVM

  • MVC:C 既管 UI 又管业务 → MassiveViewController
  • MVVM:VM 负责"数据→视图"的格式化,易测试、可绑定
swift 复制代码
final class ArticleVM: ObservableObject {
    @Published var title = ""
    func fetch() {
        // 纯逻辑,无 UIKit
    }
}

SwiftUI + Combine 让 MVVM 成为"官方亲儿子"

Combine 入门

  • Publisher:发信号
  • Subscriber:收信号
  • Operator:加工信号
swift 复制代码
let vm = TimerVM()
class TimerVM: ObservableObject {
    @Published var seconds = 0
    private var bag = Set<AnyCancellable>()
    init() {
        Timer.publish(every: 1, on: .main, in: .common)
            .autoconnect()
            .assign(to: \.seconds, on: self)
            .store(in: &bag)
    }
}

优势:类型安全、内存管理自动、与 SwiftUI 无缝

GCD:async vs sync

swift 复制代码
// 异步:不阻塞当前线程
DispatchQueue.global(qos: .userInitiated).async {
    let data = try? Data(contentsOf: url)
    DispatchQueue.main.async {
        self.imageView.image = UIImage(data: data!)
    }
}

// 同步:阻塞等待(死锁高危)
// DispatchQueue.main.sync { }  // ❌主线程等待主线程→死锁

最佳实践:UI 更新 main.async;耗时任务 global().async

网络层选型

方案 优点 缺点
URLSession 官方、0 依赖 样板多
Alamofire 链式、自动验证、上传友好 增加 500 KB
swift 复制代码
// URLSession 原生 async/await
let (data, _) = try await URLSession.shared.data(from: url)
let model = try JSONDecoder().decode(User.self, from: data)

数据持久化矩阵

场景 技术 示例
小配置 UserDefaults flag、score
大结构化 CoreData / Realm 离线文章
文件 FileManager 缓存图片
敏感 Keychain token、password

SwiftUI 属性包装器

  • @State:View 内部私有状态
  • @Binding:父子双向引用
  • @ObservedObject:外部可观察对象
  • @EnvironmentObject:全局注入
swift 复制代码
struct PlayerView: View {
    @State private var isPlaying = false          // ① 局部
    @Binding var progress: Double                // ② 父级传入
    @ObservedObject var vm: PlayerVM             // ③ 引用类型
    @EnvironmentObject var appSet: AppSettings   // ④ 全局
}

UIView 几何三兄弟

  • frame:父坐标系 → 布局
  • bounds:自身坐标系 → 绘图、子视图布局
  • center:父坐标系中心点 → 动画平移
swift 复制代码
print(view.frame)   // (x=20,y=100,width=200,height=50)
print(view.bounds)  // (x=0,y=0,width=200,height=50)
print(view.center)  // (x=120,y=125)

DiffableDataSource

告别 performBatchUpdates 崩溃:

swift 复制代码
enum Section { case main }
typealias Snapshot = NSDiffableDataSourceSnapshot<Section, Article>

var dataSource: UITableViewDiffableDataSource<Section, Article>!

func apply(_ items: [Article]) {
    var snap = Snapshot()
    snap.appendSections([.main])
    snap.appendItems(items)
    dataSource.apply(snap, animatingDifferences: true)
}

优势:一致性、动画自动、线程安全

静态库 vs 动态库

维度 静态 Framework 动态 Framework
链接时机 编译期 运行时
包大小 增大 IPA 多 App 共享可降体积
启动速度 略快 略慢
热更新 ✅(App Store 政策外)

官方建议:系统级用动态;小 SDK / 启动敏感用静态

MVVM 优劣大辩论

✅ 测试友好、UI 逻辑分离、SwiftUI 原生绑定

❌ 文件数翻倍、初学者绑定语法易踩坑

适用:中大型项目、单元测试覆盖率要求高

AutoLayout:从 Frame 到约束

swift 复制代码
// 代码约束
button.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
    button.centerXAnchor.constraint(equalTo: view.centerXAnchor),
    button.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: -20)
])

口诀:先关 mask,再激活;Anchor 链式可读性高

Combine vs RxSwift

维度 Combine RxSwift
官方
iOS 版本 ≥13 ≥9
运算符 50+ 200+
跨平台 仅 Apple Android / Web

结论:新纯 iOS 项目 Combine;多平台或复杂流 RxSwift

URLSession 实战封装

swift 复制代码
struct APIClient {
    static func request<T: Decodable>(_ endpoint: String) async throws -> T {
        guard let url = URL(string: endpoint) else { throw URLError(.badURL) }
        let (data, response) = try await URLSession.shared.data(from: url)
        guard (response as? HTTPURLResponse)?.statusCode == 200 else { throw URLError(.badServerResponse) }
        return try JSONDecoder().decode(T.self, from: data)
    }
}
// 使用
let user: User = try await APIClient.request("https://api.xxx.com/user")

Alamofire 优势

  • 链式参数封装
  • 自动 Validation(statusCode 200..<300)
  • Multipart 上传一行代码
  • RequestInterceptor 刷新 Token 无感重试

API 认证三板斧

  1. OAuth2:AccessToken + RefreshToken,标准但流程重
  2. APIKey:Header 内传 key,简单却易泄漏
  3. JWT:自包含签名+过期,无需服务端状态,注意 Payload 别放敏感

存储:全进 Keychain;HTTPS 必须;吊销策略后端控制

安全 checklist

✅ HTTPS + SSL Pinning

✅ 不落日志、不埋 Git

✅ 输入校验 + 输出转义

✅ 限流 / 防重放

✅ 定期轮换密钥

相关推荐
jh_cao12 小时前
(3)SwiftUI 的状态之上:数据流与架构(MVVM in SwiftUI)
ios·架构·swiftui
方君宇14 小时前
iOS App小组件(Widget)设置透明背景
ios
恋猫de小郭15 小时前
React 和 React Native 不再直接归属 Meta,React 基金会成立
android·前端·ios
HarderCoder1 天前
Swift 中的基本运算符:从加减乘除到逻辑与或非
ios·swift
HarderCoder1 天前
Swift 中“特性开关”实战笔记——用编译条件+EnvironmentValues优雅管理Debug/TestFlight/AppStore三环境
ios·swift
HarderCoder1 天前
Swift 并发任务中到底该不该用 `[weak self]`?—— 从原理到实战一次讲透
ios·swift
FeliksLv1 天前
iOS 集成mars xlog
ios
2501_915106321 天前
CDN 可以实现 HTTPS 吗?实战要点、部署模式与真机验证流程
网络协议·http·ios·小程序·https·uni-app·iphone
大熊猫侯佩2 天前
在肖申克监狱玩转 iOS 26:安迪的 Liquid Glass 复仇计划
ios·swiftui·swift
非专业程序员3 天前
逆向分析CoreText中的字体级联/Font Fallback机制
前端·ios