일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- Performance
- state
- 네트워크
- dataflow
- UIKit
- 달력
- ar
- arkit
- Network
- auth
- ios
- stateobject
- RxSwift
- GCD
- WWDC
- CS
- firebase
- gesture
- environmentobjet
- fullscreencover
- Animation
- 데이터최적화
- iphone
- authentication
- SwiftUI
- swift
- realitykit
- combine
- withAnimation
- Concurrency
- Today
- Total
XLOG
[UIKit] UIImage 효율적으로 사용하기 - 1 본문
프로젝트를 진행하면서 UICollectionView 와 Image를 함께 사용할 일이 많았다.
Asset을 이용하여 사용할 때는 큰 문제가 없었지만, 서버에서 이미지를 불러오면서 그 효율성에 대한 고민을 하기 시작했다.
그리기 위해 UIImage, UiImageView 가 어떻게 동작하는지 알아야 겠다는 생각을 했다.
그래서 WWDC18 에 Image and Graphics Best Practice 영상을 확인했다.
보통 이미지는 우리 데이터공간, 혹은 네트워크를 통해 다운받아 UIImage로 Load 하여 Decode 한다.
Decode를 하는 과정에서 image사이즈에 따라 image buffer의 크기가 결정된다.
Buffer 란 연속되 메모리 영역이다. Buffer엔 Data Buffer, Image Buffer 등이 있다.
즉, UIImage 는 다운 받아 Image에 대한 Data Buffer 를 Image Buffer 로 Decode 를 진행한다. 그 후 UIImageView를 통헤 Render를 하지만 이때 Size를 조정하더라도 Image Buffer 의 사이즈는 원본사이즈 그대로 유지가 되기에 메모리 낭비가 발생하게 된다.
이러한 메모리 낭비를 줄이기 위해 우리는 DownSampling 작업을 진행해야 한다.
위의 그림처럼 CGImageSource 로 ImageSize를 조정하여 Thumnail용 UIImage를 리턴하게 하여 Render를 진행하게 된다.
kCGImageSourceShouldCacheImmediately 옵션은 매우 중요하다.
그 결과 31.5 MiB 에서 18.4MiB 로 메모리 사용이 줄어든다.
또한 이걸
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPaht) -> UICollectionViewCell {}
에 적용하여 효율적으로 사용했다고 생각할 수 있는데, 이 방법 또한 권장되지는 않는다고 한다.
그 이유는 컬렉션뷰의 경우 스크롤을 하게 될 경우 새로운 행이 보이면서 url을 통해 image를 다운받아 사이즈를 줄이고 하는 이런 작업들이 매번 일어나는데 이것은 비효율적이면서 불편함을 초래할 수 있다.
또한 아이폰은 주사율에 따라 매초 60번 이상의 rerender를 진행하는데 rerender와 image를 불러오는데 있어 차이가 발생하게 되면 자연스럽지 않은 애니메이션을 볼 수 있다. 또한 배터리에도 좋지 않은 영향을 줄 것이다.
그렇기에 WWDC 영상에선 두가지 방법을 제시한다.
바로 Prefetching 과 Background decoding / downsampling 이다.
Prefetching을 실행하게 되면 다음 화면을 미리 준비하여 hitching을 대비한다. 또한 메인쓰레드는 View를 담당해야하기에 다른 쓰레드에서 작업을 진행하는 것이다.
CollectionView에 저렇게 prefetch하는 함수가 존재하는지 처음알았다. 관련된 사항에 대해 더 자세히 알고 싶으면 wwdc 영상을 또 보라고 한다.........
하지만 이 방법또한 완벽한 건 아니다. 큐를 많이 동작시킴으로서 Thread Explosion이 발생할 수 있다. 한번에 image down sampling을 8개 씩 진행하는데 내가 실제 사용할 수 있는것은 2~3개 밖에 존재하지 않을 수 있다.
그렇기에 SerialQueue를 사용하라고 한다.
wwdc에 이후 내용엔 Image Sources 를 관리하는 것에 대해서도 나온다.
Asset과 관련된 내용이 나오는데 이건 다음에 포스팅 해야겠다.
'Swift > UIKit' 카테고리의 다른 글
[UIKit] Layer 는 무엇일까? 왜 사용할까? (0) | 2023.03.01 |
---|---|
원티드 프리온보딩 챌린지 iOS 2차과정 사전 과제 (2) | 2023.02.26 |
[UIKit] Google Login With Firebase (0) | 2023.01.30 |
[UIKit]UIView에 action 추가하기 (0) | 2023.01.30 |
[UIKit] UITextField 한글 글자 수 제한 (0) | 2023.01.30 |