메인 화면에서 장소의 이미지가 로딩되는 시간을 줄이는게 아주 오래된 숙제였다.
정말 온갖 방법이란 방법은 다 시도해봤던거 같다 🥲
그러다 생각한 방법이 어차피 첫 화면에선 많아야 10개 정도의 장소만 보이는데 화면에 보이는 Cell의 이미지만 다운받을 순 없을까?
첫 화면에만 보이는 Cell의 개수를 특정하기엔 모델마다 화면 크기가 다르고 처음엔 10개만 받아라! 하기에도 애매했다.
개수로 할 수 없으니 다른 방법은 '이 Cell이 화면에 보이는가?' 를 알아내는 방법이었다.
Returns the table cell at the index path you specify.
cellForRow(at:)은 단순히는 indexPath에 해당하는 특정 Cell을 불러오는 함수다.
this method returns nil if the cell isn’t visible or if indexPath is out of range.
단순한 이 함수의 특징은 Cell이 보이는 상태가 아니면 nil을 반환한다는 것이다!
즉, 이 함수로 현재 indexPath의 Cell이 보여지는지 확인할 수 있다.
DispatchQueue.main.async { [self] in
if let updateCell = tableView.cellForRow(at: indexPath) as? PlaceCell{
getImage(place: places[indexPath.row]){ photo in
if photo != nil {
updateCell.imgPlace.image = photo
placeImages.updateValue(photo!, forKey: self.places[indexPath.row].name)
}
}
}
}
참고 : cellForRow(at:) | Apple Developer Documentation
if let 은 Optional 타입 변수를 안전하게 사용하기 위한 방법이다.
Optinal 타입은 안전하게 바인딩 할 수 있는 방법으로 비슷하게 guard let 이 있다.
코드로 예시를 들면
func check(type: String?){
if let result = type {
print(result)
}else{
print("type is nil")
}
guard let result = type else{
print("type is nil")
}
print(result)
}
- check(type: "nil이 아님")
nil이 아님
nil이 아님
- check(type: nil)
type is nil
type is nil
if let 은 변수가 nil이 아닐 때 진행하고 else 구문을 통해 nil일 때도 처리할 수 있다. if let으로 바인딩 된 상수는 if 구문 내에서만 사용가능하다는 특징이 있다.
guard let은 블록 안에서만 사용이 가능한데 값이 nil이 아닌 경우에만 코드를 진행한다. 대신 블록을 종료하기 위해 return, break, continue, throw 등 제어문 전환 명령을 함께 사용한다.
guard let은 바인딩 역할만이 아니라 Bool 타입으로 let 뒤에가 true일 때만 작동하게 할 수도 있다. 또한 if let과 다르게 guard let에서 바인딩 된 상수는 메서드 내에서 지역변수처럼 사용할 수 있다.
즉 guard letdms nil이 아닌 경우에만 관심을 가지기 문에 예외사항만 처리하고 싶다면 guard let 구문을 사용하는게 간편하고 nil과 nil이 아닐 때 모두 처리가 필요하다면 if let을 사용하는게 적절하다!
[ if let ]
- nil이 아닐 때 작동
- 상수는 구문 내에서만 사용
- nil일 때, 아닐 때 구분해서 처리 용이
[ guard let ]
- nil이면 코드 진행을 아예 안 함
- 메서드 내에서 상수 사용 가능
- 예외사항 처리 시 편리
위에서 Optional 바인딩이란 용어가 나왔는데 그럼 Optional은 무엇일까?
Optional
A type that represents either a wrapped value or nil, the absence of a value.
쉽게 말해 어떤 value 또는 nil을 나타내는 타입을 말한다.
다만 nil 값을 나타내는게 아닌 값이 없음을 뜻한다.
var optionalValue : String?
이렇게 뒤에 ?를 붙여 표시하고 자동으로 nil로 초기화된다. swift에선 optional 변수 이외에는 nil을 사용할 수 없다.
optional인 변수와 아닌 변수는 다른 타입이므로 변수 선언 시 정의해줘야 한다.
optioanl 변수를 사용하려면 unwrapping이 필요하다. optional 변수는 기본적으로 wrap 되어 value인지 nil인지 모르는 상태다.
따라서 optional 변수를 그냥 사용할 수 없고 unwrapping으로 값을 꺼내야 한다.
let realValue : Sting = optionalValue!
Fatal error: Unexpectedly found nil while unwrapping an Optional value
당연히 오류가 나게 된다ㅎㅎ
위에 경우처럼 nil이 튀어나올 경우를 대비해 미리 체크하는 것을 Optional Binding 이라 할 수 있다.
값을 확인해서 nil이 아닐 경우에만 진행하는 것인데 위에 설명한 if let ( guard let ) 구문을 이용한다.
참고... zeddios.DispatchQueue