스크롤과 이미지 다운로드

Judy·2021년 9월 29일
0

메인 화면에서 장소의 이미지가 로딩되는 시간을 줄이는게 아주 오래된 숙제였다.

정말 온갖 방법이란 방법은 다 시도해봤던거 같다 🥲

그러다 생각한 방법이 어차피 첫 화면에선 많아야 10개 정도의 장소만 보이는데 화면에 보이는 Cell의 이미지만 다운받을 순 없을까?

첫 화면에만 보이는 Cell의 개수를 특정하기엔 모델마다 화면 크기가 다르고 처음엔 10개만 받아라! 하기에도 애매했다.

개수로 할 수 없으니 다른 방법은 '이 Cell이 화면에 보이는가?' 를 알아내는 방법이었다.


1. tableView.cellForRow(at: indexPath)

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이 보여지는지 확인할 수 있다.

화면에 보이는 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


2. if let

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)
}    
  1. check(type: "nil이 아님")
    nil이 아님
    nil이 아님

  2. 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 ]

  1. nil이 아닐 때 작동
  2. 상수는 구문 내에서만 사용
  3. nil일 때, 아닐 때 구분해서 처리 용이

[ guard let ]

  1. nil이면 코드 진행을 아예 안 함
  2. 메서드 내에서 상수 사용 가능
  3. 예외사항 처리 시 편리

3. Optional

위에서 Optional 바인딩이란 용어가 나왔는데 그럼 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인 변수와 아닌 변수는 다른 타입이므로 변수 선언 시 정의해줘야 한다.

Wrapping - Unwrapping

optioanl 변수를 사용하려면 unwrapping이 필요하다. optional 변수는 기본적으로 wrap 되어 value인지 nil인지 모르는 상태다.

따라서 optional 변수를 그냥 사용할 수 없고 unwrapping으로 값을 꺼내야 한다.

let realValue : Sting = optionalValue!

!를 붙여 optinal 변수의 값을 강제로 unwrapping 한다. 물론 unwrapping 했더니 nil일 수도 있는데 optional 변수가 아닌 값에 넣었다면

Fatal error: Unexpectedly found nil while unwrapping an Optional value

당연히 오류가 나게 된다ㅎㅎ

Optional Binding

위에 경우처럼 nil이 튀어나올 경우를 대비해 미리 체크하는 것을 Optional Binding 이라 할 수 있다.

값을 확인해서 nil이 아닐 경우에만 진행하는 것인데 위에 설명한 if let ( guard let ) 구문을 이용한다.

4. DispatchQueue.main.async

참고... zeddios.DispatchQueue

profile
iOS Developer

0개의 댓글