Q:
iOS18 發(fā)布之后,收到了很多拉起相冊時的崩潰客訴朴摊。堆棧日志如下:
#0 Thread
NSInternalInconsistencyException
opportunisticDegradedImagesToReturn cannot be zero.
解析原始
0
CoreFoundation
___exceptionPreprocess + 164
6
Photos
-[PHImageManager requestImageForAsset:targetSize:contentMode:options:resultHandler:] + 172
......(略)
crash 位置還是很清晰的默垄,但是原因不清晰啊,沒見過這個報錯甚纲,網(wǎng)上也沒搜到有效信息口锭,也沒聽說 iOS18 后,相冊哪里要做額外的兼容介杆。
我們項目中的這塊代碼實現(xiàn)鹃操,簡略如下:
PHImageRequestOptions *imageRequestOptions = [[PHImageRequestOptions alloc] initWithImageRequestOptions:options];
imageRequestOptions.synchronous = YES;
imageRequestOptions.networkAccessAllowed = YES;
imageRequestOptions.resizeMode = PHImageRequestOptionsResizeModeFast;
imageRequestOptions.deliveryMode = PHImageRequestOptionsDeliveryModeOpportunistic;
[[PHImageManager defaultManager] requestImageForAsset:phAsset targetSize:targetSize contentMode:PHImageContentModeAspectFit options:imageRequestOptions resultHandler:^(UIImage * _Nullable result, NSDictionary * _Nullable info) {
// TODO: image something
}];
A:
從報錯信息看,主要是說 opportunisticDegradedImages
這個東西春哨,不能是 zero荆隘,那 opportunistic 和 degraded 這兩個關鍵詞是什么意思呢?
opportunistic:
指的是 PHImageRequestOptions
對象 deliveryMode
屬性的值悲靴,他表示請求的圖像質(zhì)量和交付優(yōu)先級臭胜。我用的默認值 PHImageRequestOptionsDeliveryModeOpportunistic
,表示平衡下圖像質(zhì)量和響應速度癞尚,也就是報錯這個關鍵詞耸三。詳情可參考這篇文章:鏈接
@property (nonatomic, assign) PHImageRequestOptionsDeliveryMode deliveryMode; // delivery mode. Defaults to PHImageRequestOptionsDeliveryModeOpportunistic
typedef NS_ENUM(NSInteger, PHImageRequestOptionsDeliveryMode) {
PHImageRequestOptionsDeliveryModeOpportunistic = 0, // client may get several image results when the call is asynchronous or will get one result when the call is synchronous
PHImageRequestOptionsDeliveryModeHighQualityFormat = 1, // client will get one result only and it will be as asked or better than asked
PHImageRequestOptionsDeliveryModeFastFormat = 2 // client will get one result only and it may be degraded
};
degraded:
這單詞是降級的意思,翻了翻 PHImageRequestOptions
的 API浇揩,allowSecondaryDegradedImage
屬性看起來比較接近仪壮,他表示除了初始的降級結果之外,如果條件允許胳徽,是否還返回一個額外的降級結果积锅。
這是 iOS17 新增的 API爽彤,官方也并沒太多的說明介紹 AppleDevelopDoc鏈接
@property (nonatomic) BOOL allowSecondaryDegradedImage API_AVAILABLE(macos(14), ios(17), tvos(17)); // in addition to the initial degraded result, an additional degraded result will be returned if conditions permit
fix 方案:
于是嘗試把 allowSecondaryDegradedImage
設為 YES 看看,然后就 OK 了缚陷。适篙。。就不崩了箫爷。嚷节。。虎锚。
if (@available(iOS 17, *)) {
imageRequestOptions.allowSecondaryDegradedImage = YES;
} else {
// Fallback on earlier versions
}
至于底層原理是為什么硫痰,我也不清楚,只是根據(jù)報錯信息窜护,蒙著改了效斑。如果有了解這塊的朋友,歡迎大家留言討論柱徙。