🍎 iOS & Swift

[iOS] commit hitch μ œκ±°ν•˜κΈ°

taeeekki 2023. 10. 26. 18:20

문제

λΉ„λ§ˆμ΄ν”Œλžœ 1.4.3 λ²„μ „μ˜ 메인 ν™”λ©΄μ—μ„œ 슀크둀 μ‹œ λŠκΉ€ ν˜„μƒμ΄ λ°œμƒν•©λ‹ˆλ‹€.

1. μ½”λ“œμ— 문제일 것이닀.
2. λ Œλ”λ§ 문제일 것이닀.

iOS μ–΄ν”Œλ¦¬μΌ€μ΄μ…˜μ˜ UI λ Œλ”λ§ 과정에 λŒ€ν•΄μ„œ μ•Œμ•„λ³΄κΈ°λ‘œ ν–ˆμŠ΅λ‹ˆλ‹€. Render Loop, Hitch λ“±λ“±μ˜ ν‚€μ›Œλ“œκ°€ λ‚˜μ˜€λ”κ΅°μš”. ν‚€μ›Œλ“œμ— λŒ€ν•΄μ„œ μ•Œμ•„λ³΄λ˜ 쀑 κ΄€λ ¨ μžˆλŠ” 것 같은 WWDC μ„Έμ…˜μ΄ λͺ‡ 개 λ‚˜μ™”μŠ΅λ‹ˆλ‹€. μš°μ„  μ˜μƒλΆ€ν„° 보기둜 ν–ˆμŠ΅λ‹ˆλ‹€.

λ‹€μŒ μ˜μƒμ„ 찾아보면 쒋을 것 κ°™μŠ΅λ‹ˆλ‹€:

 

μ˜μƒμ„ 찾아보면 μ•Œκ² μ§€λ§Œ μš°μ„  Render Loop, Commit Phase, hitch λ“±μ˜ κ°œλ…μ— λŒ€ν•΄μ„œ 이해해야 ν•©λ‹ˆλ‹€.

hitch

hitchλΌλŠ” μš©μ–΄μ— λŒ€ν•΄μ„œ μš°μ„  μ•Œμ•„λ΄…μ‹œλ‹€.

hitchλΌλŠ” μš©μ–΄λŠ” μ€„을 고리 λͺ¨μ–‘μœΌλ‘œ λ§Œλ“€μ–΄ ν™€μΉ˜λŠ” λ™μž‘μ„ μ˜λ―Έν•˜λŠ” κ²ƒμœΌλ‘œ μ‹œμž‘λœ μš©μ–΄λΌκ³  ν•©λ‹ˆλ‹€. 보톡 λŠμ„ λ¬Άκ±°λ‚˜ 맀듭을 지을 λ•Œ λ§ˆμ§€λ§‰μ— νž˜μ„ 꽉 주게 λ˜λŠ”λ° μ΄λŸ¬ν•œ λͺ¨μŠ΅μ„ λ°”νƒ•μœΌλ‘œ κ°‘μžκΈ° 움직이닀, ν™± μ›€μ§μ΄λ‹€λΌλŠ” 의미인 jerk와 λΉ„μŠ·ν•œ 의미둜 쓰이기 μ‹œμž‘ν•©λ‹ˆλ‹€.

 

WWDC μ„Έμ…˜μ„ 보면 hitchλΌλŠ” μš©μ–΄μ— λŒ€ν•œ μ„€λͺ…을 λ‹€μŒκ³Ό 같이 ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€:

 

hitchλΌλŠ” 것은 ν”„λ ˆμž„(frame)이 μ˜ˆμƒλœ μ‹œκ°„λ³΄λ‹€ μ§€μ—°λ˜κ²Œ λ‚˜νƒ€λ‚˜λŠ” μ‹œκ°„μ„ μ˜λ―Έν•˜λŠ” κ±°μ£ .

 

ν”„λ ˆμž„μ΄ μ˜ˆμƒλœ μ‹œκ°„μ— λ‚˜νƒ€λ‚˜μ§€ μ•ŠλŠ”λ‹€λŠ” 것은 μ–΄λ–€ 것을 μ˜λ―Έν•˜λŠ” κ²ƒμΌκΉŒμš”? μ•„μ΄ν°μ˜ μ£Όμ‚¬μœ¨μ€ 60Hzμž…λ‹ˆλ‹€. Hz(Refresh Rate, μ£Όμ‚¬μœ¨)은 1μ΄ˆμ— 화면을 λͺ‡ 번 κ°±μ‹ ν•  수 μžˆλŠ”μ§€μ— λŒ€ν•œ μˆ˜μΉ˜μž…λ‹ˆλ‹€. 우리의 νœ΄λŒ€ν°μ€ μ‹œκ°„μ˜ 흐름에 λ”°λΌμ„œ 보여주어야 ν•  ν™”λ©΄μ˜ μˆœκ°„, 즉 ν”„λ ˆμž„μ„ 이런 μ €λŸ° 처리λ₯Ό 톡해 μ€€λΉ„ν•©λ‹ˆλ‹€.

예λ₯Ό λ“€μ–΄μ„œ, ν”Œλ¦½λΆμ„ λ– μ˜¬λ €λ³ΌκΉŒμš”?

μ• λ‹ˆλ©”μ΄μ…˜μ²˜λŸΌ 보이게 ν•˜λ €λ©΄:

  1. μ›€μ§μž„μ΄ μ΄μ–΄μ§€λŠ” 그림을 μˆ˜μ‹­, 수백μž₯ μ€€λΉ„ν•œλ‹€.
  2. μˆœμ„œμ— 맞좰 그림을 μŒ“λŠ”λ‹€.
  3. ν•œ μž₯μ”© λΉ λ₯΄κ²Œ λ„˜κΈ΄λ‹€.

μœ„μ™€ 같은 κ³Όμ •μœΌλ‘œ 정적인 그림이 μ›€μ§μ΄λŠ” μ• λ‹ˆλ©”μ΄μ…˜μ²˜λŸΌ 보이게 λ˜λŠ” 것이죠. νœ΄λŒ€ν°λ„ λ§ˆμ°¬κ°€μ§€μž…λ‹ˆλ‹€. ν•œ μž₯의 그림이 ν•˜λ‚˜μ˜ ν”„λ ˆμž„κ³Ό λŒ€μ‘λ˜λŠ” κ±°μ—μš”. μ•„μ΄ν°μ˜ μ£Όμ‚¬μœ¨μ΄ 60Hz라고 ν–ˆμœΌλ‹ˆκΉŒ 1μ΄ˆμ— 60μž₯μ”© κ·Έλ¦Ό(ν”„λ ˆμž„)을 λΉ λ₯΄κ²Œ λ³΄μ—¬μ£Όκ²Œ λ˜λŠ” κ²ƒμž…λ‹ˆλ‹€.

 

그런데 λ§Œμ•½μ— μˆœμ„œκ°€ μ •ν•΄μ Έ μžˆλŠ” κ·Έλ¦Ό(ν”„λ ˆμž„)μ—μ„œ 쀑간에 λͺ‡ μž₯μ”© μ€€λΉ„κ°€ λŠ¦μ–΄μ§€κ±°λ‚˜ λΉ μ Έμ„œ ν‘œμ‹œλ₯Ό λͺ»ν•˜κ²Œ 되면, 맀우 λΆ€μžμ—°μŠ€λŸ¬μš΄ μ• λ‹ˆλ©”μ΄μ…˜μ΄ 보여지겠죠. μ‹€μ œλ‘œ iOSμ—μ„œλŠ” ν”„λ ˆμž„μ„ μ€€λΉ„ν•˜λŠ” 단계가 λ³„λ„λ‘œ μ‘΄μž¬ν•˜λŠ”λ° μ–΄λ–€ 이유둜 μΈν•΄μ„œ ν”„λ ˆμž„ μ€€λΉ„κ°€ 제 λ•Œ λ˜μ§€ μ•ŠμœΌλ©΄ 화면에 ν‘œμ‹œν•  수 μ—†μ–΄μ„œ λΆ€μžμ—°μŠ€λŸ¬μš΄ μ• λ‹ˆλ©”μ΄μ…˜(λŠκΉ€ ν˜„μƒ)이 λ°œμƒν•˜κ²Œ λ©λ‹ˆλ‹€.

 

Render Loop: ν”„λ ˆμž„ μ€€λΉ„λ˜λŠ” 단계, λ·°κ°€ κ·Έλ €μ§€λŠ” 단계

μœ„μ—μ„œ μ΄μ•ΌκΈ°ν•œ ν”„λ ˆμž„μ„ μ€€λΉ„ν•˜λŠ” 단계λ₯Ό Render Loop라고 ν•©λ‹ˆλ‹€.

앱을 μ‚¬μš©ν•˜λ‹€λ³΄λ©΄ 정말 λ‹€μ–‘ν•œ μ΄λ²€νŠΈκ°€ λ°œμƒν•©λ‹ˆλ‹€. 이벀트 μ€‘μ—λŠ” μ‚¬μš©μžμ™€ μƒν˜Έμž‘μš©ν•˜λŠ” μ΄λ²€νŠΈκ°€ 있죠. κ·Έ μ€‘μ—λŠ” ν„°μΉ˜ μ΄λ²€νŠΈλ„ μžˆμŠ΅λ‹ˆλ‹€. κ°€λ Ή λ²„νŠΌμ„ λˆŒλŸ¬μ„œ 화면에 μžˆλŠ” λ·°λ₯Ό μ›€μ§μ΄λŠ” 상황이라고 μƒκ°ν•΄λ΄…μ‹œλ‹€. κ·Έ μˆœκ°„μ— ν„°μΉ˜ μ΄λ²€νŠΈκ°€ μ•±μœΌλ‘œ μ „λ‹¬λ˜κ³ , λ‹€μŒ UI에 λŒ€ν•œ λ³€κ²½ 사항이 μ μš©λ©λ‹ˆλ‹€. μ–΄λ–»κ²Œ 움직여야 ν•  μ§€, μ΅œμ’…μ μœΌλ‘œλŠ” λ·°κ°€ μ–΄λ–€ μœ„μΉ˜μ— μžˆμ–΄μ•Ό ν• μ§€ 등에 정보가 μ •ν•΄μ§€κ² μ£ ? μ΄λŸ¬ν•œ 정보λ₯Ό λ°”νƒ•μœΌλ‘œ ν”„λ ˆμž„μ„ μ™„μ„±μ‹œν‚€κΈ° μœ„ν•œ μž‘μ—…μ„ ν•˜κΈ° μœ„ν•΄ 그런 λ‚΄μš©λ“€μ΄ 운영체제둜 μ „λ‹¬λ©λ‹ˆλ‹€. μ΄λŸ¬ν•œ 과정듀이 앱을 μ‚¬μš©ν•˜λŠ” λ™μ•ˆ μ—°μ†μ μœΌλ‘œ μ§„ν–‰λ©λ‹ˆλ‹€.

 

λ‹¨κ³„λŠ” 더 μ„ΈλΆ€μ μœΌλ‘œ λ‚˜λˆ„μ–΄μ§€λŠ”λ°μš”.(λ‚΄λΆ€μ˜ μ„Έκ³„λŠ” μ–΄λ ΅λ‹€ 정말πŸ₯Ή)
크게 3κ°€μ§€μ˜ 단계가 λ³‘λ ¬μ μœΌλ‘œ μˆ˜ν–‰λ©λ‹ˆλ‹€:

  1. App 단계 : μ΄λ²€νŠΈκ°€ 처리되고 UIκ°€ λ³€κ²½λ˜λŠ” 단계
  2. Render 단계 : UIκ°€ μ‹€μ œλ‘œ λ Œλ”λ§λ˜λŠ” 단계
  3. Display 단계 : ν”„λ ˆμž„μ΄ 화면에 λ””μŠ€ν”Œλ ˆμ΄λ˜λŠ” 단계

λͺ¨λ“  단계가 μ „λΆ€ μ€‘μš”ν•˜μ§€λ§Œ 개인적으둜 Render 단계가 κ°€μž₯ μ€‘μš”ν•˜λ‹€κ³  μƒκ°ν•©λ‹ˆλ‹€. 뷰의 계측 ꡬ쑰, λ ˆμ΄μ•„μ›ƒ λ“±λ“±μ˜ μ—¬λŸ¬κ°€μ§€ 정보λ₯Ό μ‘°ν•©ν•΄μ„œ ν”„λ ˆμž„(κ·Έλ¦Ό)을 λ§Œλ“€μ–΄λ‚΄λŠ” 단계라고 μƒκ°ν•˜λ©΄ 될 것 κ°™μ•„μš”. 이 역할을 λ‹΄λ‹Ήν•˜λŠ” μΉœκ΅¬κ°€ GPU μž…λ‹ˆλ‹€. λ ˆμ΄μ–΄ 트리, λ Œλ” μ„œλ²„ λ“±λ“± μ—¬λŸ¬ μš©μ–΄κ°€ 또 λ‚˜μ˜€μ§€λ§Œ κ·Έ 뢀뢄에 λŒ€ν•΄μ„œλŠ” μ’€ 더 찾아보면 μ’‹κ² κ³ , 결둠은 μ‹€μ§ˆμ μΈ 그림이 λ§Œλ“€μ–΄μ§€λŠ” λ‹¨κ³„λΌλŠ” κ²ƒμž…λ‹ˆλ‹€.

각 λ‹¨κ³„μ—λŠ” 16.67ms(1μ΄ˆμ— 60ν”„λ ˆμž„μ΄ μ€€λΉ„λ˜κ³  κ·Έλ €μ Έμ•Ό ν•˜λ‹ˆκΉŒ 1초λ₯Ό 60으둜 λ‚˜λˆˆ 수치)의 μ œν•œμ‹œκ°„μ΄ μžˆμ–΄μš”. μ œν•œμ‹œκ°„μ„ μ§€ν‚€μ§€ λͺ»ν•˜λ©΄ κ·Έ ν”„λ ˆμž„μ€ 화면에 보여지지 λͺ»ν•˜λŠ” 것이죠. (마치 과제λ₯Ό 마감 κΈ°ν•œ μ•ˆμ— ν•˜μ§€ λͺ»ν•˜λŠ” λŠλ‚Œμ΄λž„κΉŒ.. κ΅μˆ˜λ‹˜ μ£„μ†‘ν•΄μš”..) κ·Έλž˜μ„œ 제 μ‹œκ°„ μ•ˆμ— μž‘μ—…μ„ μ™„μˆ˜ν•˜λŠ” 것이 맀우 μ€‘μš”ν•˜κ² μ£ ?

생각을 쑰금만 해보면 '무거운 μž‘μ—…(λΉ„μš©μ΄ 많이 λ“œλŠ” μž‘μ—…)μ΄λ‚˜ λΆˆν•„μš”ν•œ μž‘μ—…μ€ μ€„μ΄κ±°λ‚˜ ν•˜μ§€ μ•ŠλŠ” 것이 μ’‹λ‹€'λŠ” 결둠을 λ„μΆœν•΄ λ‚Ό 수 μžˆμŠ΅λ‹ˆλ‹€.

 

ν•΄κ²° κ³Όμ •

μœ„μ—μ„œ λͺ‡ κ°€μ§€ κ°œλ…μ„ μ‚΄νŽ΄λ³΄λ©΄μ„œ '무거운 μž‘μ—…(λΉ„μš©μ΄ 많이 λ“œλŠ” μž‘μ—…)μ΄λ‚˜ λΆˆν•„μš”ν•œ μž‘μ—…μ€ μ€„μ΄κ±°λ‚˜ ν•˜μ§€ μ•ŠλŠ” 것이 μ’‹λ‹€'λΌλŠ” 결둠을 λ„μΆœν–ˆμ–΄μš”. λ„ˆλ¬΄ λ‹Ήμ—°ν•œ 말인데 사싀 개발자둜써 κ°œλ°œν•˜λŠ” κ·Έ μˆœκ°„μ—λŠ” 잘 μΈμ§€ν•˜μ§€ λͺ»ν•˜κ³  또 신경을 μ“°κΈ°λž€ μ°Έ μ–΄λ ΅μ£ .. μ—¬ν•˜νŠΌ 그럼 μ–΄λ–»κ²Œ 문제λ₯Ό ν•΄κ²°ν•  수 μžˆμ„κΉŒμš”?

  1. 슀크둀 μ‹œ λŠκΉ€ ν˜„μƒμ΄ λ°œμƒν•œλ‹€.
  2. 이것이 hitchλΌλŠ” 것을 μ•Œκ²Œλ˜μ—ˆλ‹€.
  3. Render Loop의 λ Œλ”λ§ λ‹¨κ³„μ—μ„œ λ¬Έμ œκ°€ 생긴 것 κ°™λ‹€. (κ°€μ •)
  4. 무거운 μž‘μ—…μ΄λ‚˜ λΆˆν•„μš”ν•œ μž‘μ—…λ•Œλ¬Έμ— λ Œλ”λ§ μ‹œκ°„μ΄ 많이 κ±Έλ¦¬λŠ” 것 κ°™λ‹€. (κ°€μ •)

μ΄λŸ¬ν•œ κ³Όμ •μœΌλ‘œ 생각이 μ „κ°œλ˜μ—ˆκ³ , instrumentsλ₯Ό κ°€μ§€κ³  κ°€μ •ν–ˆλ˜ 상황이 정말 λ§žλŠ”μ§€ ν™•μΈν•΄λ³΄κΈ°λ‘œ ν–ˆμŠ΅λ‹ˆλ‹€.

instruments

Xcode 12λΆ€ν„°λŠ” instrumentsμ—μ„œ Animation HitchesλΌλŠ” ν…œν”Œλ¦Ώμ„ μ œκ³΅ν•©λ‹ˆλ‹€.

μœ„μ˜ ν…œν”Œλ¦Ώμ„ μ΄μš©ν•΄μ„œ λ©”μΈν™”λ©΄μ˜ 슀크둀 λ™μž‘λ§Œ μΈ‘μ •ν•΄λ³΄μ•˜μŠ΅λ‹ˆλ‹€.

before

λ°œμƒν•˜κ³  μžˆλŠ” hitch의 κ°œμˆ˜κ°€ 16개 정도 μžˆμŠ΅λ‹ˆλ‹€.

 

Main Thread μͺ½μ—μ„œ μ–΄λ–€ 일이 μΌμ–΄λ‚˜κ³  μžˆλŠ”μ§€ μ‚΄νŽ΄λ³΄λ‹ˆ, μ•„λ¬΄λž˜λ„ MainCVC(μ»¬λ ‰μ…˜ λ·° μ…€)μ—μ„œ 이미지λ₯Ό μ„€μ •ν•΄μ£ΌλŠ” 곳에 λ¬Έμ œκ°€ μžˆλŠ” 것 κ°™μŠ΅λ‹ˆλ‹€. μž‘μ—… μ‹œκ°„μ„ 생각보닀 μ—„μ²­ μž‘μ•„λ¨Ήκ³  μžˆλ„€μš”. μ‹€μ œλ‘œ μ…€μ—μ„œ 이미지λ₯Ό μ„€μ •ν•΄μ£ΌλŠ” μ½”λ“œλ₯Ό 주석 μ²˜λ¦¬ν•˜κ³  츑정을 λ‹€μ‹œ ν•΄λ³΄λ‹ˆ hitchκ°€ 거의 λ°œμƒν•˜μ§€ μ•Šλ‹€μ‹œν”Ό μ€„μ–΄λ“œλŠ” 것을 확인할 수 μžˆμ—ˆμŠ΅λ‹ˆλ‹€.

그럼 μ΄μ œλŠ” 이미지 μ„€μ • λΆ€λΆ„λ§Œ κ°œμ„ μ„ ν•΄μ£Όλ©΄ λ¬Έμ œλŠ” 해결이 λ˜λŠ” κ±°κ² μ£ ?

이미지 μ„€μ •

μ•± λ‚΄μ—μ„œλŠ” 이미지 캐싱 및 λ‹€μš΄λ‘œλ“œμ— Kingfisher 라이브러리λ₯Ό μ‚¬μš©ν•˜κ³  있고, 이λ₯Ό ν•œ 번 λž˜ν•‘ν•΄μ„œ 이미지λ₯Ό μ„€μ •ν•΄μ£Όκ³  μžˆμ—ˆμŠ΅λ‹ˆλ‹€. λΆ„λͺ… 이전에 μΊμ‹œ 정책도 μ„€μ •ν•΄μ£Όκ³  λ©”λͺ¨λ¦¬ κ°œμ„ κΉŒμ§€ μ‹œμΌœμ€¬λŠ”λ° μ™œ 그런 κ±ΈκΉŒμš”? ν•œ κ°€μ§€λ₯Ό λ†“μΉ˜κ³  μƒκ°ν•˜κ³  μžˆμ—ˆμŠ΅λ‹ˆλ‹€.

슀크둀 ν•  λ•Œλ§ˆλ‹€ μˆ˜λ§Žμ€ 이미지 λ‹€μš΄λ‘œλ“œ μš”μ²­μ΄ λ°œμƒν•˜κ³  μžˆμ—ˆμŠ΅λ‹ˆλ‹€.

λ””μŠ€ν”Œλ ˆμ΄ λ˜λŠ” 셀에 ν•œν•΄μ„œ 이미지 λ‹€μš΄λ‘œλ“œ μž‘μ—…μ„ μˆ˜ν–‰ν•˜κ³ , κ·Έ μ™Έμ˜ 셀에 λŒ€ν•΄μ„œλŠ” λ‹€μš΄λ‘œλ“œλ₯Ό μ·¨μ†Œν•˜λŠ” μž‘μ—…λ„ ν•„μš”ν–ˆμŠ΅λ‹ˆλ‹€. λ˜ν•œ 같은 μš”μ²­μ— λŒ€ν•΄μ„œλŠ” μ€‘λ³΅μœΌλ‘œ μž‘μ—…μ„ μˆ˜ν–‰ν•  ν•„μš”λ„ μ—†μ—ˆμ£ . Kingfisherλ₯Ό μ‚¬μš©ν•˜κ³  μžˆλŠ” μƒν™©μ΄μ–΄μ„œ μš°μ„ μ€ μ œκ³΅λ˜λŠ” λ©”μ„œλ“œλ‚˜ ν”„λ‘œνΌν‹°λ₯Ό μ΄μš©ν•΄μ„œ ν•΄κ²°ν•˜κ³ μž ν–ˆμŠ΅λ‹ˆλ‹€.

// Cell

var task: Kingfisher.DownloadTask?

...

func configureFor(plan: PlanViewModel) {
  guard let url = URL.decodeURL(urlString: plan.imageURLString) else {
    #if DEBUG
      print("invalid url")
    #endif
    return
  }

  let processor = DownsamplingImageProcessor(size: .init(width: 500, height: 500))
  task = KingfisherManager.shared.retrieveImage(with: url, options: [.processor(processor)]) { [weak self] result in
    switch result {
    case let .success(r):
      self?.imageView.image = r.image
    case let .failure(error):
      print("error: \(error) or cancelled")
    }
  }

  planId = plan.planId
  isScrap = plan.isScraped

  homePlanPropertiesView.configureFor(plan: plan)
}

// CollectionView DataSource
func collectionView(
  _ collectionView: UICollectionView,
  didEndDisplaying _: UICollectionViewCell,
  forItemAt indexPath: IndexPath
) {
  switch cells[indexPath.section] {
  case .homePlanCell:
    let cell = collectionView.dequeueCell(HomePlanCell.self, for: indexPath)
    cell.task?.cancel()
  default:
    break
  }
}
 
  1. Cellμ•ˆμ— μž‘μ—…μ„ μˆ˜λ™μœΌλ‘œ μ·¨μ†Œν•  수 μžˆλ„λ‘ Task에 λŒ€ν•œ ν”„λ‘œνΌν‹°λ₯Ό μ„ μ–Έν•΄μ£Όμ—ˆμŠ΅λ‹ˆλ‹€.
  2. 셀을 Configureν•˜λŠ” λ©”μ„œλ“œ λ‚΄μ—μ„œ 이미지λ₯Ό λ‹€μš΄λ‘œλ“œν•˜λŠ” μž‘μ—…μ„ ν”„λ‘œνΌν‹°μ— λ‹΄μ•„μ£Όμ—ˆμŠ΅λ‹ˆλ‹€.
  3. Displayκ°€ λλ‚œ 셀에 λŒ€ν•΄μ„œλŠ” λ‹€μš΄λ‘œλ“œκ°€ μ§„ν–‰ 쀑인 μž‘μ—…μ΄ μžˆμ„ λ•Œ μ·¨μ†Œν•˜λ„λ‘ ν–ˆμŠ΅λ‹ˆλ‹€.

전체 μ½”λ“œλ₯Ό 첨뢀할 μˆ˜λŠ” μ—†μ§€λ§Œ μœ„μ™€ 같은 방법을 μ΄μš©ν•΄μ„œ 문제λ₯Ό ν•΄κ²°ν•˜λ €κ³  ν–ˆμŠ΅λ‹ˆλ‹€.

κ²°λ‘ 

μŠ€ν¬λ‘€μ„ 정말 λΉ λ₯΄κ²Œ ν•˜λŠ” μƒν™©μ—μ„œ λͺ¨λ“  셀에 λŒ€ν•΄ 이미지 λ‹€μš΄λ‘œλ“œ μž‘μ—…μ„ μˆ˜ν–‰ν•˜κ²Œ λœλ‹€λ©΄ λ§Žμ€ λΆ€ν•˜λ₯Ό 쀄 수 밖에 μ—†κ³ , λ Œλ”λ§ μ„±λŠ₯이 μ €ν•˜λ  수 μžˆμŠ΅λ‹ˆλ‹€. 그렇기에 보여지지 μ•ŠλŠ” 셀에 λŒ€ν•΄μ„œλŠ” λ‹€μš΄λ‘œλ“œ μž‘μ—…μ„ μ·¨μ†Œν•˜λŠ” 것이 ν•„μš”ν–ˆλ˜ 것이죠. λ‹Ήμž₯은 이미지 μ²˜λ¦¬μ—μ„œ 문제λ₯Ό λ°œκ²¬ν•  수 μžˆμ—ˆμ§€λ§Œ, 이외에도 λ Œλ”λ§ μ„±λŠ₯에 영ν–₯을 쀄 수 μžˆλŠ” μΌ€μ΄μŠ€λŠ” 무수히 λ§Žμ„ 수 μžˆκΈ°μ— μ•žμœΌλ‘œλ„ λΉ„μŠ·ν•œ λ¬Έμ œκ°€ λ°œμƒν•˜λ©΄ μš°μ„  instruments둜 ν™•μΈν•˜λŠ” μŠ΅κ΄€μ„ 듀이면 쒋을 것 κ°™μŠ΅λ‹ˆλ‹€.

after

μœ μ˜λ―Έν•˜κ²Œ hitch의 κ°œμˆ˜κ°€ 쀄어든 것을 확인할 수 μžˆμŠ΅λ‹ˆλ‹€. λΉ„λ§ˆμ΄ν”Œλžœ 1.4.4 버전을 λ‹€μš΄λ°›μ•„ 메인화면을 μŠ€ν¬λ‘€ν•΄λ³΄λ©΄ λΆ€λ“œλŸ½κ²Œ μŠ€ν¬λ‘€λ˜λŠ” 것을 ν™•μΈν•˜μ‹€ 수 μžˆμŠ΅λ‹ˆλ‹€.

 

## 링크

https://github.com/taekki-labs/note/wiki/Commit-Hitch-%EC%A0%9C%EA%B1%B0%ED%95%98%EA%B8%B0

 

Commit Hitch μ œκ±°ν•˜κΈ°

Contribute to taekki-labs/note development by creating an account on GitHub.

github.com

 

λŒ“κΈ€μˆ˜0