2017-12-06 16 views
0

선택적 요소가 있지만 테이블 뷰에 해당 요소를 표시 할 때 오류가 발생합니다. 참고로이 요소는 JSON API 피드에서 가져온 이미지입니다. 그 요소를 사용하여 요소 unwrapping 그 이해합니다! 좋은 생각은 아니지만 xcode에서 제안한 바이며 다른 옵션은 제공하지 않습니다. 그 제안을 따르는 경우, 응용 프로그램이 충돌하여 이 "선택 값을 언 래핑하는 동안 예기치 않게 nil을 찾았습니다."라고 표시됩니다. 누구든지 URL에서 이미지를 표시하는 방법을 알고 있습니다. 지금까지 제가 가지고있는 코드는 다음과 같습니다.선택 요소를 래핑 해제 할 때의 오류

struct PlayerStats:Decodable { 
    let personaname: String? 
    let score: Double? 
    let solo_competitive_rank: Int? 
    let avatar: String? 
} 

문제는 cellForRowAt func의 "avatar"요소 때문입니다.

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 
    guard let cell = tableView.dequeueReusableCell(withIdentifier: "rankCell") as? RankTableViewCell else { return UITableViewCell() } 
    cell.nameLabel.text = rank[indexPath.row].personaname 

    if let imageURL = URL(string: rank[indexPath.row].avatar) { 
     DispatchQueue.global().async { 
      let data = try? Data(contentsOf: imageURL) 
      if let data = data { 
      guard let avatar = UIImage(data: data) else { return } 
       DispatchQueue.main.async { 
        cell.avatarImage.image = avatar 
       } 
      } 
     } 
    } 

    return cell 
} 
+1

'Data (contentsOf : imageURL)'를 발송해도 메인 스레드를 차단하지 않아도 인터넷에서 콘텐츠를 다운로드하는 데 '데이터'의 이니셜 라이저를 사용해서는 안됩니다. 이니셜 라이저는 네트워크 URL이 아닌 __local__ 파일 URL에서 내용을로드하는 데에만 사용해야합니다. –

+0

저를 시정 해 주셔서 감사합니다. 나는 지금까지 배운 자료를 바탕으로이 지식을 얻었으므로이 문제를 인식하지 못했습니다. –

+1

* "xcode에서 내가 제안한 것"* -이 사이트의 Swift 질문 중 절반은 Xcode의 멋진 "기능"으로 인해 발생한다고 생각합니다. 나는 언젠가 애플이 언젠가 이것을 바꿀 것을 정말로 희망한다. – rmaddy

답변

1

avatarnil 인 경우 코드가 충돌합니다. 당신은 또한 URL에 직접 avatar를 디코딩 두 단계

if let avatar = rank[indexPath.row].avatar, 
    let imageURL = URL(string: avatar) { ... 

에 URL을 만들어야 JSONDecoder

let avatar: URL? 

는 그런 다음 코드

if let imageURL = rank[indexPath.row].avatar { 

을 단축 할 수 있습니다 그리고 당신은 강력하다 Dávid가 언급 한대로 동기 Data(contentsOf: API를 사용하지 않기를 권고합니다. 비동기 사용 URLSession

1

avatar 속성을 안전하게 제거해야한다는 것 외에도 코드에 몇 가지 개념적인 문제가 있습니다.

우선 동기화 메서드이기 때문에 tableView(_:cellForRowAt:) 내부에서 비동기 작업을 수행하면 안되므로 UITableViewCell이 반환되어 이미지가 네트워크 URL에서 다운로드 될 수 있습니다. 별도의 함수로 이미지 다운로드를 수행하고 비동기 작업이 완료되면 테이블 뷰 (또는 적어도 해당하는 행/섹션)를 다시로드해야합니다.

둘째, 인터넷에서 콘텐츠를 다운로드 할 때 이니셜 라이저 Data(contentsOf:)을 사용하지 마십시오. Data(contentsOf: imageURL)을 파견해도 주 스레드를 차단하지 않으므로 데이터 초기화 프로그램을 인터넷에서 콘텐츠를 다운로드하는 데 사용해서는 안됩니다. 이니셜 라이저는 네트워크 URL이 아닌 로컬 파일 URL에서 내용을로드하는 데에만 사용해야합니다.