diff --git a/Tusker/Caching/ImageCache.swift b/Tusker/Caching/ImageCache.swift index 2e04fbd9..7681ab6e 100644 --- a/Tusker/Caching/ImageCache.swift +++ b/Tusker/Caching/ImageCache.swift @@ -18,7 +18,7 @@ class ImageCache { let cache: Cache - var requests = [URL: RequestGroup]() + private var groups = [URL: RequestGroup]() init(name: String, memoryExpiry expiry: Expiry) { let storage = MemoryStorage(config: MemoryConfig(expiry: expiry)) @@ -43,14 +43,18 @@ class ImageCache { completion?(data) return nil } else { - if let completion = completion, let group = requests[url] { + if let completion = completion, let group = groups[url] { return group.addCallback(completion) } else { - let group = RequestGroup(url: url) - let request = group.addCallback(completion) - group.run { (data) in - try? self.cache.setObject(data, forKey: key) + let group = RequestGroup(url: url) { (data) in + if let data = data { + try? self.cache.setObject(data, forKey: key) + } + self.groups.removeValue(forKey: url) } + groups[url] = group + let request = group.addCallback(completion) + group.run() return request } } @@ -61,29 +65,30 @@ class ImageCache { } func cancelWithoutCallback(_ url: URL) { - requests[url]?.cancelWithoutCallback() + groups[url]?.cancelWithoutCallback() } - class RequestGroup { + private class RequestGroup { let url: URL + private let onFinished: (Data?) -> Void private var task: URLSessionDataTask? private var requests = [Request]() - init(url: URL) { + init(url: URL, onFinished: @escaping (Data?) -> Void) { self.url = url + self.onFinished = onFinished } deinit { task?.cancel() } - func run(cache: @escaping (Data) -> Void) { + func run() { task = URLSession.shared.dataTask(with: url, completionHandler: { (data, response, error) in guard error == nil, let data = data else { self.complete(with: nil) return } - cache(data) self.complete(with: data) }) task!.resume() @@ -123,11 +128,12 @@ class ImageCache { callback(data) } } + self.onFinished(data) } } class Request { - weak var group: RequestGroup? + private weak var group: RequestGroup? private(set) var callback: ((Data?) -> Void)? private(set) var cancelled: Bool = false diff --git a/Tusker/Screens/Profile/ProfileTableViewController.swift b/Tusker/Screens/Profile/ProfileTableViewController.swift index ec85650c..c1dd5c61 100644 --- a/Tusker/Screens/Profile/ProfileTableViewController.swift +++ b/Tusker/Screens/Profile/ProfileTableViewController.swift @@ -16,20 +16,8 @@ class ProfileTableViewController: EnhancedTableViewController { var accountID: String! - var pinnedStatuses: [(id: String, state: StatusState)] = [] { - didSet { - DispatchQueue.main.async { - self.tableView.reloadData() - } - } - } - var timelineSegments: [[(id: String, state: StatusState)]] = [] { - didSet { - DispatchQueue.main.async { - self.tableView.reloadData() - } - } - } + var pinnedStatuses: [(id: String, state: StatusState)] = [] + var timelineSegments: [[(id: String, state: StatusState)]] = [] var older: RequestRange? var newer: RequestRange? @@ -124,6 +112,12 @@ class ProfileTableViewController: EnhancedTableViewController { self.mastodonController.persistentContainer.addAll(statuses: statuses) { self.pinnedStatuses = statuses.map { ($0.id, .unknown) } + let indexPaths = (0..