develop

Subscript Optional 본문

iOS

Subscript Optional

pikachu987 2021. 1. 2. 11:24
반응형

이전글 2021/01/01 - [iOS] - Subscript 에서 설명한 Subscript에 값을 Optional로 사용합니다.

 

 

Dictionary에 Subscript를 사용하면 Optional로 나온다.

let dict = ["a": 1, "b": 2]
let a = dict["a"]
print(a)
Optional(1)

 

하지만 Array에 Subscript를 사용하면 데이터 그대로 나오게 된다.

let array = [1, 2, 3, 4, 5, 6, 7]
let first = array[0]
print(first)
1

 

UITableView 나 UICollectionView 를 사용할때 Array로 데이터를 가져올때 Array가 변하게 되면

Fatal error: Index out of range 에러를 볼 수 있게 된다.

이런 상황에서 에러를 내지 않는 방법은

if indexPath.row <= array.count - 1 {
    // Success
} else {
    // Fail
}

이렇게 코드를 짜야 한다. 어레이의 갯수보다 row나 item이 작을때 subscript로 가져오는 것이다.

하지만 더 간단하고 깔끔한 방법이 있다.

Dictionary처럼 Subscript시 Optional로 가져올 수 있다.

 

indices

let array = [1, 2, 3, 4, 5, 6, 7]
print(array.indices)
0..<7

indices는 Array의 전체 Range를 가져온다.

 

~=

print(1...10 ~= 1)
print(1...10 ~= 2)
print(1...10 ~= 3)
print(1...10 ~= 10)
print(1...10 ~= 11)
true
true
true
true
false

~= 는 사이에 있다는 오퍼레이터이다.

1...10 사이에 1이 있다 = true

 

그러면 indices 프로퍼티와 ~= 오퍼레이터를 합쳐서

Array의 Range안에 해당 index가 있으면 데이터를 리턴하고 없으면 nil값을 주면 된다.

extension Array {
    subscript(safe index: Int) -> Element? {
        get {
            return self.indices ~= index ? self[index] : nil
        }
    }
}
var array = [1, 2, 3, 4, 5, 6, 7]
print(array[safe: 1])
print(array[safe: 5])
print(array[safe: 10])
Optional(2)
Optional(6)
nil

subscript로 데이터를 가져와서 index가 Array의 Range안에 있으면 데이터를 가져오고 없으면 nil을 리턴한다.

 

 

Set도 마찬가지로

extension Array {
    subscript(safe index: Int) -> Element? {
        set {
            if self.indices ~= index, let newValue = newValue {
                self[index] = newValue
            }
        }
        get {
            return self.indices ~= index ? self[index] : nil
        }
    }
}
var array = [1, 2, 3, 4, 5, 6, 7]
array[safe: 0] = 5
array[safe: 10] = 10
print(array)
[5, 2, 3, 4, 5, 6, 7]

index가 Array의 Range에 포함되면 해당 index에 데이터를 추가하고

없으면 넘어간다.

반응형

'iOS' 카테고리의 다른 글

Escaping noescaping  (0) 2021.01.04
Enumeration  (0) 2021.01.03
Subscript  (0) 2021.01.01
Swizzling  (0) 2020.12.31
IBDesignable, IBInspectable  (0) 2020.12.30
Comments