You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将PHPhotoLibraryChangeObserver迁移到Swift 6并适配严格并发检查?

Swift 6 下 PHPhotoLibraryChangeObserver 适配崩溃问题解决

问题背景

以下代码在Swift 6中触发编译错误:

extension AssetGridViewController: PHPhotoLibraryChangeObserver {
    func photoLibraryDidChange(_ changeInstance: PHChange) {
        Task { @MainActor in
            guard let changes = changeInstance.changeDetails(for: fetchResult) else { return }
            fetchResult = changes.fetchResultAfterChanges
        }
    }
}

AssetGridViewController为普通UIViewController实例,编译错误提示:

Main actor-isolated instance method 'photoLibraryDidChange' cannot be used to satisfy nonisolated protocol requirement

按照错误提示的两种修复方案操作后,均会触发运行时崩溃:EXC_BREAKPOINT (code=1, subcode=0x105b7c400):

  • 方案1:给方法添加nonisolated修饰
  • 方案2:给协议扩展添加@preconcurrency修饰

解决方案

问题根源在于PHPhotoLibraryChangeObserver的回调方法在非主线程执行,直接使用@MainActor修饰Task会捕获当前非隔离上下文与Main Actor的冲突。正确实现方式如下:

extension AssetGridViewController: PHPhotoLibraryChangeObserver {
    nonisolated func photoLibraryDidChange(_ changeInstance: PHChange) {
        Task { [weak self] in
            guard let self = self, let changes = changeInstance.changeDetails(for: self.fetchResult) else { return }
            await MainActor.run {
                self.fetchResult = changes.fetchResultAfterChanges
                // 在此添加UI更新逻辑,如刷新集合视图
            }
        }
    }
}

核心要点

  • nonisolated修饰方法:满足协议的非隔离要求,消除编译错误,明确该方法不绑定Main Actor。
  • 弱引用self:避免Task持有强引用导致内存泄漏。
  • await MainActor.run切换线程:在Main Actor上下文内更新实例属性和UI,既保证并发安全,又符合UI操作必须在主线程的要求。

此实现既能通过Swift 6的并发安全检查,又不会触发运行时崩溃。


内容的提问来源于stack exchange,提问作者Andrés Pizá Bückmann

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 18:04:52