2016-09-12 3 views
1

Безопасно ли и имеет смысл отложить загрузку асинхронного изображения для ячейки? Идея заключается в том, что я хочу, чтобы функция обратного вызова из URLSession.shared.image (...) выполнялась после создания ячейки, и только один раз вызов cellForRow (at: indexPath) действителен, поскольку я считаю, что без отсрочки этого метода в этот момент должен вернуться нуль.Lazy загрузка изображения на UITableViewCell с использованием defer

  • URLSession.shared.image является частным расширения, которое выполняет задание данных и дает вытекающий обратный вызов, только если URL содержится в аргументе корректен и содержит изображение.

  • setImage (изображение: анимированный) - это частное расширение, которое позволяет вам установить изображение в UIImageView с помощью простой анимации.

Если отсрочка не подходит, укажите альтернативу.

Любая обратная связь будет оценена, спасибо!

override func tableView(_ tableView: UITableView, cellForRowAt 
    indexPath: IndexPath) -> UITableViewCell { 

    let cell = baseCell as! MyCell 
    let datum = data[indexPath.row] 
    cell.imageView.setImage(placeholderImage, for: .normal) 

    defer { 
     URLSession.shared.image(with: datum.previewURL) { image, isCached in 
      if let cell = tableView.cellForRow(at: indexPath) as? MyCell { 
       cell.imageView.setImage(image, animated: !isCached) 
      } 
     } 
    } 

    return cell 
} 
+0

do u пытается использовать SDWebImage для него –

ответ

1

NSHipster имеют хорошую статью о том, как/когда использовать, here Отложить.

Я не использовал бы defer таким образом. Намерение отложить - очистить/освободить память в одном блоке кода, а не рассеивать его во многих точках выхода.

Подумайте о том, что у вас есть несколько операндов-хранителей во всей функции и необходимо освободить память в каждом из них.

Вы не должны использовать это, чтобы просто добавить дополнительный код после факта.

Как уже упоминалось @jagveer, существует много сторонних библиотек, которые уже делают это, например кеширование SDWebImage. AFNetworking и AlamoFire также имеют встроенную систему. Не нужно повторно изобретать колесо, когда оно уже было сделано.

0

В этом случае defer не работает. defer устанавливает блок, который вызывается, когда область действия выходит, что вы делаете немедленно.

Я думаю, что вы хотите запланировать выполнение блока в другом потоке с помощью Dispatch. Чтобы обновить интерфейс, вам нужно вернуться в основной поток.

Как это может произойти позже, вам необходимо убедиться, что ячейка все еще используется для одной и той же записи и не использовалась повторно, так как пользователь прокручивал дальше. Получение ячейки снова не является хорошей идеей, если она была повторно использована, так как вы в конечном итоге снова инициировали первоначальный вызов. Обычно я добавляю некоторый идентификатор к настраиваемому классу UITableViewCell для проверки.

Кроме того, вы не создаете ячейку, просто извлекаете ее из какой-либо другой переменной. Это, вероятно, будет проблемой, если имеется более одной ячейки.

override func tableView(_ tableView: UITableView, cellForRowAt 
indexPath: IndexPath) -> UITableViewCell { 

    let cell = tableView.dequeueReusableCell(withIdentifier: "base") as! MyCell 
    cell.row = indexPath.row 
    let datum = data[indexPath.row] 
    cell.imageView.setImage(placeholderImage, for: .normal) 

    DispatchQueue.global().async { 
     // Runs in a background thread 
     URLSession.shared.image(with: datum.previewURL) { image, isCached in 
      DispatchQueue.main.async { 
       // Runs in the main thread; safe for updating the UI 
       // but check this cell is still being used for the same index path first! 
       if cell.row == indexPath.row { 
        cell.imageView.setImage(image, animated: !isCached) 
       } 
      } 
     } 
    } 

    return cell 
} 

 Смежные вопросы

  • Нет связанных вопросов^_^