-
PHCachingImageManager requestImage 이미지 중복 SWIFT TASK CONTINUATION MISUSEiOS 2023. 2. 7. 19:17반응형
PHCachingImageManager.default().requestImage
PHAsset 에서 이미지를 가져올 때 해당 메서드를 사용합니다.
무심코 아래와 같이 option 없이 사용할 수 있는데요PHCachingImageManager.default().requestImage(for: asset, targetSize: PHImageManagerMaximumSize, contentMode: .aspectFit, options: nil) { image, info in if let image = image { continuation.resume(returning: image) } }
이럴 때 주의해야 할 점이 있습니다.
이 함수는 기본적으로 비동기적으로 동작합니다.
비동기적으로 사용했을 때 Photos는 고화질 이미지를 준비할 동안 일시적으로 저화질 이미지를 제공한다고 하네요.
따라서 이미지를 (result handler block) 을 여러 번 반환할 수 있습니다. (거의 그렇더군요;;)그래서! 분명 asset 개수보다 더 많은 중복 이미지 (저화질 이미지, 고화질 이미지 섞여서)가 생길 수 있습니다.
비동기로 호출한다면 이런 문제를 막기 위해 아래와같이 동기 옵션을 추가해주면 됩니다.
let option = PHImageRequestOptions() option.isSynchronous = true PHCachingImageManager.default().requestImage(for: asset, targetSize: PHImageManagerMaximumSize, contentMode: .aspectFit, options: options) { image, info in if let image = image { continuation.resume(returning: image) } }
뿐만 아니라 제 경우 swift 동시성을 사용할 때 문제가 발생했는데요,
requestImage 의 result completion handler 를 처리하기 위해 아래와 같이 사용하려고 했었답니다.func loadImage(asset: PHAsset, size: CGSize, resizeMode: PHImageRequestOptionsResizeMode = .exact, deliveryMode: PHImageRequestOptionsDeliveryMode? = nil) async -> UIImage? { return await withCheckedContinuation { continuation in PHCachingImageManager.default().requestImage(for: asset, targetSize: PHImageManagerMaximumSize, contentMode: .aspectFit, options: nil) { image, info in if let image = image { continuation.resume(returning: image) } } } }
그랬더니 아래와 같은 에러가 발생했습니다 ;;
아직 동시성을 깊게 공부하지 못하고 막 걸음마 떼는 수준이라 적잖이 당황했었는데요,,,Thread 1: Fatal error: SWIFT TASK CONTINUATION MISUSE: loadImage(asset:size:resizeMode:deliveryMode:) tried to resume its continuation more than once, returning Optional(<UIImage:0x600003ca7600 anonymous {1668, 2500} renderingMode=automatic(original)>)!
continuation 을 여러 번 resume 해서 발생했다고 하는데 뭘 잘못했나 한참 고민했네요..
위에서 설명드린 것처럼 PHCachingImageManager.default().requestImage 가 이미지를 여러 번 호출해서 문제가 됐었던 것 같아요.도움이 되셨다면 좋겠네요.
읽어주셔서 감사합니다!반응형'iOS' 카테고리의 다른 글
[SceneConfiguration] Info.plist contained no UIScene configuration dictionary (looking for configuration named "(no name)") 에러 해결 (0) 2023.02.13 이미지 포맷 요약 - 비트맵, 벡터 방식 / 손실 압축, 무손실 압축 / JPG, GIF, PNG, SVG (0) 2023.02.09 [iOS] 이미지 권한 얻기 (0) 2023.02.03 decode vs decodeIfPresent (0) 2022.12.14 [iOS] APNs 를 통한 Push 알림 이해하기 (0) 2022.12.07