SwiftUI自定义相册:为PHAsset添加选中状态的实现疑问
给PHAsset添加选中状态的两种实现方式
你之前的扩展代码无法生效,是因为缺少关联对象的核心实现逻辑,以下是两种可行的解决办法:
方案一:修复关联对象扩展
直接补充关联对象的底层调用代码,给PHAsset添加selected属性:
import Photos // 定义唯一的关联对象Key,避免冲突 private enum AssociatedKeys { static var selected = "selected" } extension PHAsset { var selected: Bool { get { // 从关联对象取值,默认未选中 return objc_getAssociatedObject(self, &AssociatedKeys.selected) as? Bool ?? false } set { // 将选中状态存入关联对象 objc_setAssociatedObject(self, &AssociatedKeys.selected, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) } } }
使用时直接修改或访问asset.selected即可,比如:
// 标记选中 assetList[0].selected = true // 判断是否选中 let isSelected = assetList[0].selected
方案二:使用包装类(更推荐)
由于PHAsset是系统框架类,直接用关联对象存在潜在的生命周期风险,更稳妥的方式是创建包装类绑定资产和选中状态:
import Photos class AssetWrapper: ObservableObject { let asset: PHAsset @Published var isSelected: Bool init(asset: PHAsset, isSelected: Bool = false) { self.asset = asset self.isSelected = isSelected } } // 将原数组替换为包装类数组 @Published var assetList: [AssetWrapper] = [] // 转换原PHAsset数组的示例代码 // let phAssets: [PHAsset] = ... // 你的原始资产数组 // assetList = phAssets.map { AssetWrapper(asset: $0) }
这种方式的优势是:
- 选中状态通过
@Published自动触发UI更新,适配SwiftUI的响应式机制 - 完全隔离系统类的修改,逻辑更清晰,避免关联对象的潜在问题
内容的提问来源于stack exchange,提问作者gaohomway
相关产品推荐
相关产品推荐

