티스토리 뷰

반응형

 

 

문제 파악하기

 

Swift에서 배열의 요소에 접근할 경우를 생각해볼게요.

 

let fooArray = [1,2,3]

print(fooArray[0]) // 1 출력

 

위의 상황에서는 문제없이 결괏값이 출력돼요.

그럼 배열의 범위를 벗어날 경우는 어떻게 될까요?

 

let fooArray = [1,2,3]

print(fooArray[100]) // Index out of range 에러 발생

 

당연히 범위를 벗어나는 에러가 발생하죠. 여기서 문제는, 결괏값이 옵셔널이라 nil로 반환되는 것이 아니라 에러가 된다는 것이에요.

혹시 배열의 요소에 접근한 결과가 옵셔널인지 타입을 확인해볼게요.

 

let fooArray = [1,2,3]

print(type(of:fooArray[0])) // Int 출력

 

옵셔널의 Int가 아니라 그냥 Int가 출력돼요.

문제는 "있으면 출력해주고 없으면 에러를 반환" 이라는 점이에요.

 

이게 큰 문제가 될 수 있는 상황은 앱을 구현할 때에요.

 

앱에서 어떤 배열에서 요소를 가져와야 하는 상황을 가정해볼게요.

 

func cafeArticle(at index: Int) -> CafeArticle {
    return self.cafeArticleList[index]
}

 

이 상황에서 cafeArticleList의 범위를 넘어서는 index 값이 들어가면 어떻게 될까요?

값을 반환하지 못하는 것을 떠나서 앱이 에러를 발생시키며 멈춰버릴 거예요.

 

앱 사용자의 측면에서 안 좋은 경험이 되겠죠?

그래서 이 문제를 해결하기 위해 안전하게 요소에 접근하는 기능을 구현해요.

 

 

안전하게 접근하는 기능 구현하기

 

// MARK: - Array

extension Array {
  subscript(safe index: Int) -> Element? {
    return self.indices ~= index ? self[index] : nil
  }
}

 

확장 기능을 통해 기능을 구현해요.

subscript를 통해 서브 스크립트 기능을 추가하는데 결과는 옵셔널(Element?)로 반환돼요.

 

조금 낯설 수 있는 문법이 "~="인데, 이것은 contains를 의미해요.

indices는 index의 복수형인데, 해석해보면 "배열의 인덱스의 범위 안에 index가 포함되어있으면 Array[index]를 반환하고, 범위를 벗어나면 nil을 반환하라에요." 

 

다시 문제 상황에 적용해보면

 

func cafeArticle(at index: Int) -> CafeArticle? {
    return self.cafeArticleList[safe: index]
}

 

로 구현 가능하겠죠?

 

이제는 혹시나 배열에 원하는 인덱스가 존재하지 않더라도 앱이 멈추는 게 아니라 옵셔널 처리를 통해 원하는 설계를 구현할 수 있어요 :]

반응형
댓글