PHAssetChangeRequest.deleteAssets无响应问题求助
问题分析与解决办法
针对你在iPhone 11 Pro(iOS 15.0)上调用PHAssetChangeRequest.deleteAssets时completionHandler始终不执行的问题,以下是常见原因和对应的解决思路:
1. 待删除资产集合无效
- 可能原因:
deleteAccess为空、包含已被删除的无效资产,或者没有正确转换为NSFastEnumeration类型。PhotoKit在没有有效变更操作时,可能不会触发completion回调。 - 解决办法:
- 先校验
deleteAccess的数量,确保包含至少1个有效PHAsset; - 优先使用
PHFetchResult作为删除对象(更符合PhotoKit的设计),示例代码:let fetchResult = PHAsset.fetchAssets(withLocalIdentifiers: assetIds, options: nil) PHPhotoLibrary.shared().performChanges { PHAssetChangeRequest.deleteAssets(fetchResult) } completionHandler: { success, error in // 此时应正常触发回调 } - 如果用Swift数组,确保正确转换:
deleteAssets(yourAssetArray as NSFastEnumeration)。
- 先校验
2. 照片权限不足或权限范围限制
- 可能原因:iOS 15对照片权限管控更严格,若仅拥有「添加照片」权限,或开启「有限权限」但待删除资产不在授权访问范围内,删除操作会被静默拦截,导致completion不触发。
- 解决办法:
- 检查当前权限状态,确保申请的是
.readWrite权限:PHPhotoLibrary.requestAuthorization(for: .readWrite) { status in guard status == .authorized || status == .limited else { // 权限不足,提示用户开启对应权限 return } // 在这里执行删除操作 } - 若为「有限权限」,确认待删除的资产属于用户授权访问的相册/内容。
- 检查当前权限状态,确保申请的是
3. 主线程阻塞或PhotoKit变更队列异常
- 可能原因:completionHandler默认在主线程回调,若主线程被长时间阻塞,回调无法执行;或者存在未完成的PhotoKit变更操作,导致队列卡死。
- 解决办法:
- 确保调用
performChanges的代码在主线程执行(虽然官方允许任意线程,但主线程更稳定); - 检查是否有其他并发的PhotoKit变更操作,避免同时触发多个变更请求;
- 临时重启APP,排查是否是队列卡死的偶发问题。
- 确保调用
4. 资产本身不可删除
- 可能原因:部分资产(如系统默认相册内的照片、未下载完成的iCloud资产、共享相册中无删除权限的资产)无法被删除,若这类资产混入待删除列表,可能导致整个变更流程中断。
- 解决办法:
- 提前校验每个资产的可删除性:
let validAssets = yourAssetArray.filter { $0.canPerform(.delete) } guard !validAssets.isEmpty else { // 无有效可删除资产,直接做对应处理 return } // 使用validAssets执行删除操作
- 提前校验每个资产的可删除性:
调试建议
- 在
performChanges的变更block内添加打印,确认该block是否被执行; - 先尝试删除单个已知有效的本地资产,验证completion是否正常回调,以此定位是资产列表问题还是全局逻辑问题。
内容的提问来源于stack exchange,提问作者Ten
相关产品推荐
相关产品推荐

