-
Notifications
You must be signed in to change notification settings - Fork 0
[FIX] Timer가 계속 메모리에 남아 동작하는 문제 수정 #181
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
- Timer 자체를 약한 참조로 수정 - reuse시 타이머 정지 - 홈 화면의 뷰 사이클에 맞춰 타이머 시작/정지
개요홈 화면 컨트롤러의 생명 주기 이벤트와 배너 섹션 셀의 메모리 관리를 개선했습니다. 뷰가 나타날 때 배너 자동 스크롤을 재개하고, 사라질 때 중지하도록 구성했으며, 타이머 순환 참조를 방지하고 셀 재사용 및 해제 시 정리 로직을 추가했습니다. 변경 사항
시퀀스 다이어그램sequenceDiagram
participant VC as HomeController
participant CV as UICollectionView
participant Cell as ImageBannerSectionCell
participant Timer as AutoScrollTimer
Note over VC: viewWillAppear()
VC->>CV: indexPathForItem(row: 0, section: 0)
CV->>Cell: 셀 조회
Cell->>Timer: startAutoScroll() 시작
Timer->>Cell: 자동 스크롤 활성화
Note over VC: viewWillDisappear()
VC->>CV: indexPathForItem(row: 0, section: 0)
CV->>Cell: 셀 조회
Cell->>Timer: stopAutoScroll() 중지
Timer-->>Cell: 타이머 무효화
Cell->>Cell: UI 업데이트 (버튼, 플래그)
Note over Cell: prepareForReuse() 또는 deinit
Cell->>Timer: stopAutoScroll() 호출
Timer-->>Cell: 타이머 정리
Note over Cell: 메모리 안전 보장
코드 리뷰 난이도 추정🎯 2 (Simple) | ⏱️ ~12분
시
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (1)
Poppool/PresentationLayer/Presentation/Presentation/Scene/Home/Main/View/ImageBannerSection/ImageBannerSection/ImageBannerSectionCell.swift (1)
103-103: 들여쓰기 일관성 확인이 필요합니다.이 줄의 들여쓰기가 주변 코드와 다른 것으로 보입니다(탭 문자 사용으로 추정). 프로젝트의 코딩 스타일 가이드에 맞춰 일관된 들여쓰기를 사용하는 것이 좋습니다.
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
Poppool/PresentationLayer/Presentation/Presentation/Scene/Home/Main/HomeController.swift(2 hunks)Poppool/PresentationLayer/Presentation/Presentation/Scene/Home/Main/View/ImageBannerSection/ImageBannerSection/ImageBannerSectionCell.swift(2 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
Poppool/PresentationLayer/Presentation/Presentation/Scene/Home/Main/HomeController.swift (1)
Poppool/PresentationLayer/Presentation/Presentation/Scene/Home/Main/View/ImageBannerSection/ImageBannerSection/ImageBannerSectionCell.swift (2)
stopAutoScroll(86-92)startAutoScroll(96-110)
🔇 Additional comments (5)
Poppool/PresentationLayer/Presentation/Presentation/Scene/Home/Main/View/ImageBannerSection/ImageBannerSection/ImageBannerSectionCell.swift (3)
14-14: 타이머 약한 참조 변경이 적절합니다.
Timer를weak으로 선언한 것은 올바른 접근입니다.scheduledTimer로 생성된 타이머는 run loop에 의해 유지되므로, 셀이 타이머를 강하게 참조할 필요가 없으며 이를 통해 잠재적인 retain cycle을 방지할 수 있습니다.
76-76: 셀 재사용 시 타이머 정리가 적절합니다.
prepareForReuse()에서stopAutoScroll()을 호출하여 셀이 재사용될 때 타이머를 정리하는 것은 좋은 관행입니다. 이를 통해 이전 셀 인스턴스의 타이머가 계속 실행되는 것을 방지할 수 있습니다.
81-83: deinit에서의 정리가 적절합니다.셀이 메모리에서 해제될 때
stopAutoScroll()을 호출하여 타이머를 정리하는 것은 리소스 누수 방지를 위한 좋은 방어적 프로그래밍입니다.Poppool/PresentationLayer/Presentation/Presentation/Scene/Home/Main/HomeController.swift (2)
43-46: 뷰가 사라질 때 타이머를 중지하는 것은 좋습니다.메모리 누수를 방지하기 위해
viewWillDisappear에서 타이머를 중지하는 것은 적절한 접근입니다.다만,
stopBannerAutoScroll()이 셀이 보이지 않을 때 작동하지 않을 수 있으므로, 사용자가 스크롤하여 배너 셀이 화면 밖에 있을 때의 동작을 테스트하여 타이머가 적절히 중지되는지 확인하세요.
40-41:viewWillAppear에서의 배너 재시작 시점 재검토 권장코드는
if let으로 안전하게 nil을 처리하므로 크래시 위험은 없습니다. 다만viewWillAppear는viewDidAppear보다 먼저 호출되므로, 이 시점에 컬렉션 뷰 레이아웃이 완료되지 않아 셀이 접근 불가능할 수 있습니다. 결과적으로 배너 자동 스크롤이 화면 전환 시 신뢰성 있게 시작되지 않을 수 있습니다.다음 중 하나를 고려하세요:
viewDidAppear로 변경 (레이아웃 완료 후)- 또는 컬렉션 뷰의 layout completion을 기다린 후 타이머 시작
| private func stopBannerAutoScroll() { | ||
| let indexPath = IndexPath(row: 0, section: 0) // 배너 섹션 인덱스 | ||
| if let cell = mainView.contentCollectionView.cellForItem(at: indexPath) as? ImageBannerSectionCell { | ||
| cell.stopAutoScroll() | ||
| } | ||
| } | ||
|
|
||
| private func restartBannerAutoScroll() { | ||
| let indexPath = IndexPath(row: 0, section: 0) | ||
| if let cell = mainView.contentCollectionView.cellForItem(at: indexPath) as? ImageBannerSectionCell { | ||
| cell.startAutoScroll() | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cellForItem(at:) 사용의 한계를 고려해야 합니다.
두 헬퍼 메서드 모두 cellForItem(at:)을 사용하여 배너 셀에 접근하는데, 이 메서드는 셀이 현재 화면에 보이는 경우에만 셀을 반환합니다. 사용자가 스크롤하여 배너가 화면 밖에 있는 경우, 이 메서드들은 아무 동작도 하지 않습니다.
더 견고한 접근 방법을 고려하세요:
- 셀 자체의 생명주기 메서드(
willMove(toWindow:)등)에서 타이머를 관리 - 또는 뷰 컨트롤러에서 배너 섹션의 타이머 상태를 직접 추적
다음 개선 방안을 적용할 수 있습니다:
private func stopBannerAutoScroll() {
let indexPath = IndexPath(row: 0, section: 0)
if let cell = mainView.contentCollectionView.cellForItem(at: indexPath) as? ImageBannerSectionCell {
cell.stopAutoScroll()
}
// 대안: 섹션 데이터 모델에 상태를 저장하여 셀이 나타날 때 적용
}
private func restartBannerAutoScroll() {
let indexPath = IndexPath(row: 0, section: 0)
if let cell = mainView.contentCollectionView.cellForItem(at: indexPath) as? ImageBannerSectionCell {
cell.startAutoScroll()
}
// 대안: 섹션 데이터 모델에 상태를 저장하여 셀이 나타날 때 적용
}또는 UICollectionViewDelegate의 willDisplay 메서드를 활용하는 방법도 고려하세요.
🤖 Prompt for AI Agents
Poppool/PresentationLayer/Presentation/Presentation/Scene/Home/Main/HomeController.swift
lines 138-150: stopBannerAutoScroll() and restartBannerAutoScroll() rely on
cellForItem(at:) which returns a cell only if it's visible, so they silently do
nothing when the banner cell is offscreen; fix by tracking the banner timer
state in the controller or section model and ensuring the cell applies that
state when it appears, or move timer control into the cell lifecycle: (1) add a
Bool flag (e.g., isBannerAutoScrollEnabled) in the view controller or section
data and set it in stopBannerAutoScroll/restartBannerAutoScroll instead of only
calling cell methods, (2) implement collectionView(_:willDisplay:forItemAt:) to
start/stop the cell’s auto-scroll based on that flag when the cell is about to
appear, or (3) alternatively, move timer management into ImageBannerSectionCell
(override willMove(toWindow:) or didMoveToWindow) so the cell starts/stops its
timer when added/removed from window and expose public start/stop only for
explicit controller overrides.
fix/#180: Timer가 계속 메모리에 남아 동작하는 문제 수정 - Timer 자체를 약한 참조로 수정 - reuse시 타이머 정지 - 홈 화면의 뷰 사이클에 맞춰 타이머 시작/정지
📌 이슈
✅ 작업 사항
Summary by CodeRabbit
릴리스 노트