vc1 выдвигает на vc2 и в vc2.
В vc2 у меня есть массив строк, которые я конвертирую в URL, которые в конечном итоге проходят через URLSession, а возвращаемые изображения преобразуются в изображения с фильтрами.Как только я получаю отфильтрованное изображение в обратном вызове URLSession, я сохраняю его в кеше.
Я хочу, чтобы отфильтрованные изображения, которые были возвращены, отображались в точном порядке, который находится в массиве строк.Я следовал за этим ответом и использую DispatchGroup + Семафоры, и все работает нормально, порядок отфильтрованных изображений возвращается в точном порядке.
Проблема, с которой я столкнулся, заключается в том, что если пользователь возвращается обратнок vc1, затем нажимает на vc2, когда приведенный ниже код запускается и видит, что в кеше есть первое отфильтрованное изображение ("str1"), он добавляет его в FilterArray и переходит к dispatchGroup.notify
.Отфильтрованные изображения, связанные с «str1» из массива, - это единственное, что добавляется, а изображения из «str2» и «str3» - нет.
Кэш может очищать или не очищать отфильтрованные изображения, связанные с "str2", "str3", и если он их очищал, тогда цикл должен продолжать обратный вызов URLSession, но это не так.Но если это не очистило их, это также не добавляет их. Вот где возникает моя проблема, цикл перестает работать, как только кэш ударил. Я впервые использую семафор, поэтому я не уверен, откуда возникают проблемы.
Чтобы обойти проблему, я просто удалил кеш, и все работает нормально, но это также означает, что я не получаю преимущества от использования кеша.
let imageCache = NSCache<AnyObject, AnyObject>()
let arrOfStringsAsUrls = ["str1", "str2", "str3", "maybe more strings..."]
var filteredArray = [UIImage]()
let dispatchGroup = DispatchGroup()
let dispatchQueue = DispatchQueue(label: "any-label-name")
let dispatchSemaphore = DispatchSemaphore(value: 0)
dispatchQueue.async {
for str in arrOfStringsAsUrls {
dispatchGroup.enter()
guard let url = URL(string: str) else {
dispatchSemaphore.signal()
dispatchGroup.leave()
return
}
if let cachedImage = imageCache.object(forKey: str as AnyObject) as? UIImage {
self?.filteredArray.append(cachedImage)
dispatchSemaphore.signal()
dispatchGroup.leave()
return
}
URLSession.shared.dataTask(with: url, completionHandler: { (data, response, error) in
if let error = error {
dispatchSemaphore.signal()
dispatchGroup.leave()
return
}
guard let data = data, let image = UIImage(data: data) else {
dispatchSemaphore.signal()
dispatchGroup.leave()
return
}
DispatchQueue.main.async{ [weak self] in
let filteredImage = self?.addFilterToImage(image)
self?.imageCache.setObject(image, forKey: str as AnyObject)
self?.filteredArray.append(filteredImage)
dispatchSemaphore.signal()
dispatchGroup.leave()
}
}).resume()
dispatchSemaphore.wait()
}
dispatchGroup.notify(queue: dispatchQueue) { in
// reloadData() and do some other stuff on the main queue
}
}