From 244659c262509dde560d48ebc9f5429d2ea92e09 Mon Sep 17 00:00:00 2001 From: Shadowfacts Date: Sun, 1 Mar 2020 18:33:44 -0500 Subject: [PATCH] Fix intermittent crash If a status in a conversation view controller creates a work item to update the timestamp in 1 minute, but the view controller is deinit'd before that time elapses, the mastodonController instance will be nil, resulting in a crash. The DispatchWorkItems's are cancelled by the respective cell deinit methods. But if the work item has already begun, cancelling it has no effect, potentially leading to a crash in the conditions described above are true. Using a weak reference to self fixes this. Additionally, don't unnecessarily recreate the work items every time. They don't capture any local variables, only self, so nothing changes. --- .../ActionNotificationGroupTableViewCell.swift | 6 ++++-- .../FollowNotificationGroupTableViewCell.swift | 6 ++++-- .../FollowRequestNotificationTableViewCell.swift | 6 ++++-- Tusker/Views/Status/TimelineStatusTableViewCell.swift | 6 ++++-- 4 files changed, 16 insertions(+), 8 deletions(-) diff --git a/Tusker/Views/Notifications/ActionNotificationGroupTableViewCell.swift b/Tusker/Views/Notifications/ActionNotificationGroupTableViewCell.swift index 597c37391d..e38417de53 100644 --- a/Tusker/Views/Notifications/ActionNotificationGroupTableViewCell.swift +++ b/Tusker/Views/Notifications/ActionNotificationGroupTableViewCell.swift @@ -115,8 +115,10 @@ class ActionNotificationGroupTableViewCell: UITableViewCell { delay = nil } if let delay = delay { - updateTimestampWorkItem = DispatchWorkItem { [unowned self] in - self.updateTimestamp() + if updateTimestampWorkItem == nil { + updateTimestampWorkItem = DispatchWorkItem { [weak self] in + self?.updateTimestamp() + } } DispatchQueue.main.asyncAfter(deadline: .now() + delay, execute: updateTimestampWorkItem!) } else { diff --git a/Tusker/Views/Notifications/FollowNotificationGroupTableViewCell.swift b/Tusker/Views/Notifications/FollowNotificationGroupTableViewCell.swift index aa112e75eb..b5f57ad1e2 100644 --- a/Tusker/Views/Notifications/FollowNotificationGroupTableViewCell.swift +++ b/Tusker/Views/Notifications/FollowNotificationGroupTableViewCell.swift @@ -104,8 +104,10 @@ class FollowNotificationGroupTableViewCell: UITableViewCell { delay = nil } if let delay = delay { - updateTimestampWorkItem = DispatchWorkItem { [unowned self] in - self.updateTimestamp() + if updateTimestampWorkItem == nil { + updateTimestampWorkItem = DispatchWorkItem { [weak self] in + self?.updateTimestamp() + } } DispatchQueue.main.asyncAfter(deadline: .now() + delay, execute: updateTimestampWorkItem!) } else { diff --git a/Tusker/Views/Notifications/FollowRequestNotificationTableViewCell.swift b/Tusker/Views/Notifications/FollowRequestNotificationTableViewCell.swift index a483b3ac04..0f46fa4792 100644 --- a/Tusker/Views/Notifications/FollowRequestNotificationTableViewCell.swift +++ b/Tusker/Views/Notifications/FollowRequestNotificationTableViewCell.swift @@ -78,8 +78,10 @@ class FollowRequestNotificationTableViewCell: UITableViewCell { delay = nil } if let delay = delay { - updateTimestampWorkItem = DispatchWorkItem { [unowned self] in - self.updateTimestamp() + if updateTimestampWorkItem == nil { + updateTimestampWorkItem = DispatchWorkItem { [weak self] in + self?.updateTimestamp() + } } DispatchQueue.main.asyncAfter(deadline: .now() + delay, execute: updateTimestampWorkItem!) } else { diff --git a/Tusker/Views/Status/TimelineStatusTableViewCell.swift b/Tusker/Views/Status/TimelineStatusTableViewCell.swift index 4b0e0917a5..e586a36fe3 100644 --- a/Tusker/Views/Status/TimelineStatusTableViewCell.swift +++ b/Tusker/Views/Status/TimelineStatusTableViewCell.swift @@ -110,8 +110,10 @@ class TimelineStatusTableViewCell: BaseStatusTableViewCell { delay = nil } if let delay = delay { - updateTimestampWorkItem = DispatchWorkItem { [unowned self] in - self.updateTimestamp() + if updateTimestampWorkItem == nil { + updateTimestampWorkItem = DispatchWorkItem { [weak self] in + self?.updateTimestamp() + } } DispatchQueue.main.asyncAfter(deadline: .now() + delay, execute: updateTimestampWorkItem!) } else {