Swift

Safe Array

GREEN.1229 2021. 7. 24. 09:19

안녕하세요. 그린입니다🟢

이번 포스팅에서는 배열에 대해 안전하게 조회하고 인덱스를 접근하는 방법에 대해 간략히 알아보겠습니다🙋🏻

 

배열에 대해 안전하게 접근하지 못할때 아래와 같은 에러를 런타임에서 많이 겪어보셨을겁니다.

fatal error: Array index out of range

바로 접근한 배열의 인덱스가 범위 밖, 즉 없다는 에러 메시지입니다.

 

if let등 아래와 같이 옵셔널바인딩을 안전하게 해줬다고 생각했는데 왜 이런 문제가 나타난걸까요?

struct Person {
  let name = "bob"
  let age = 10
  ...
}
let onePerson = Person()
let twoPerson = Person()

let people: [Person] = [onePerson, twoPerson]

if let person = people {
  ...
  print(person[0].name)
  ...
  people.remove(person[0])
}

이 부분에서 컴파일 타임에선 에러가 없지만 런타임으로 코드를 동작시키면 print(person[0].name)에서 위와 같은 에러가 나타나곤 합니다.

왜.. 그런걸까요?

이건 people의 정보가 없는것이 아니고 people의 배열안에 정보가 nil값이 들어있어 발생합니다.

이에 더욱 안전하게 people이 존재하는지 파악하기 위해선 isNotEmpty나 조건문에서 0번째 인덱스를 접근하도록 두가지 방향을 설정해야합니다.

 

1. isNotEmpty

 : 해당 배열에 값이 들어 있는지 파악하는 방식으로 위의 에러를 피할 수 있습니다.

...
if people.isNotEmpty {
  ...
  print(people[0].name)
  ...
  people.remove(people[0])
}

이렇게 한다면 안전하겠지만 대신 print문에서 0번째 인덱스를 접근하는 첨자 참조 크래시가 발생할 수도 있습니다.

이에 좀 더 안전하게 접근해보도록 하죠!

 

2. safe

 : safe로 해당 배열이 있는지 판단하고 접근

if let person = people[safe: 0] {
  ...
  print(person.name)
  ...
  people.remove(person)
}

safe로 해당 배열의 인덱스 값이 있는지 안전하게 조회하고 접근하여 사용한다면 print에서 첨자 참조 크래시를 방지할 수 있습니다.

그렇지만 해당 safe는 첫번째 인덱스를 접근하는것보다 중간에 있는 인덱스를 안전하게 조회/접근할때 사용합니다.

이에 마지막 방법을 알아보겠습니다.

 

3. first

 : 인덱스의 첫번째 요소 접근

if let person = people.first {
  ...
  print(person.name)
  ...
  people.remove(person)
}

이렇게 옵셔널 바인딩 부분에서 first로 접근한다면 첨자 참조 크래시도 나지 않고 안전하게 접근 및 사용할 수 있습니다.

 

이렇게 간단한 배열 조회에도 다양하고 안전하게 접근하는 방법에 대해 알아봤습니다.

어느 방식을 어떻게 적용할지 고민하여 잘 사용하는 개발자가 되길..👍