Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
31 |
Tags
- 화면전환
- escaping
- list
- http
- ScrollView
- Refresh
- 글또
- error
- singleton
- mvvm
- array
- PushNotification
- uikit
- NotificationCenter
- class
- SWIFTUI
- Observer
- segue
- Switch
- IOS
- viewlifecycle
- Animation
- calendar
- apns
- SWIFT
- Git
- 고차함수
- struct
- self
- protocol
Archives
- Today
- Total
seong_hye, the developer
오류 해결) swift:600: Fatal error: Index out of range 본문
❗️ "Index out of range" error 해결 ❗️
Swift에서 가장 자주 마주하게 되는 오류라고 할 수 있음
Index out of range = 배열이나 컬렉션의 범위를 벗어난 인덱스에 접근할 때 발생하는 에러
🔹 자주 발생하는 원인
- 인덱스를 하드코딩 했는데 값이 없을 경우
let arrays = [1, 2, 3, 4, 5]
for i in 0...5 { // error ~> 갯수는 5개지만 인덱스는 0~4까지임
}
- 빈 배열에서 접근 시도
var arrays = []
print(arrays[0]) // error ~> 아직 값이 들어오지 않았음
- 비동기 작업에서 배열 변경 후 접근
var arrays = []
arrays.getArray()
...
if ( ... ) {
arrays.removeAll() // ~> 어떤 경우 배열을 삭제하는 코드
...
print(arrays) // error ~> 경우의 수를 잘못 설정해 지워진 뒤에 접근 해 오류 발생
- 잘못된 루프 범위 사용
for i in 0..array.count { //error ~> 범위가 잘못 설정되어 오류 발생
...
}
🔹 안전하게 사용하는 방법
➡️ 배열의 count로 먼저 확인
if index < array.count {
let value = array[index]
}
➡️ indices 속성 사용
if array.indices.contains(index) {
print(array[index])
}
➡️ 옵셔널 방식으로 안전하게
Swift에는 기본적으로 없지만 Array에 확장을 추가하면 편리하게 사용 가능
let value = array[safe:index] // 확장 사용 시 안전
extension Array {
subscript(safe index: Int) -> Element? {
return indices.contains(index) ? self[index] : nil
}
}
⚠️ 하지만 내가 오류가 발생한 이유
문제 상황 요약 (Ex)
- 1번 뷰 (ListView)
-> 배열을 사용해서 리스트를 보여줌 (items)
- 2번 뷰 (DetailView)
items 배열을 값 복사로 파라미터로 전달
- 2번 뷰에서 수정 후 1번 뷰로 돌아오자
-> 1번 뷰가 다시 리렌더링되며 index out of range 발생
struct ListView: View {
@State private var items = [1,2,3,4,5]
@State private var selectedIndex = 1
var body: some View {
NavigationLink(destination:SecondView(items: items)) {
Text(items[selectedIndex]) // error 발생
}
}
}
✅ 오류가 발생한 이유
SwiftUI는 상태가 변하면 뷰를 다시 계산하고 그리기 때문에 다음과 같은 상황이 생긴 것
1. 2번 뷰에서 조작한 결과 (ex. delete)가 상태를 변경함 -> 이 변경이 @State, @ObservedObject를 통해 1번 뷰에도 영향을 줌2. SwiftUI는 1번 뷰를 다시 렌더링3. 그런데 1번 뷰 내부에서 여전히 이전 인덱스 (ex. items[selectedIndex])를 사용4. 현재 items.count가 줄어든 상태 -> index out of range 오류 발생
✅ 해결한 방법
상태 변화에 따라 데이터 다시 받아올 수 있도록 수정
.onChange(of: items) { newItems in
if !newItems.indices.contains(selectedIndex) {
selectedIndex = 0
}
}
onChange를 사용해서 배열 자체나 관련된 사항의 변화가 생기면
새로 받아오거나 초기화 할 수 있도록 수정함
'IOS > Error' 카테고리의 다른 글
오류 해결) unrecognized selector sent to class 오류 해결 (0) | 2024.01.06 |
---|---|
오류 해결) On branch is up to date with 'origin/브랜치이름'. 오류 해결 (0) | 2024.01.06 |
오류 해결) Cannot use instance member ' ' within property initializer; property initializers run before 'self' is avaliable 해결 (0) | 2023.08.24 |
오류 해결) List Refreshable 오류 (0) | 2022.12.13 |
오류 해결 ) 'Receiver (< >) has no segue with identifier '' 오류 해결 (0) | 2022.10.18 |
Comments