I have code that I am repeating a bunch. I want to update things on the main thread, UI stuff.
public func closeGraph() {
DispatchQueue.main.sync{_closeGraph()}
}
That's easy enough, but what if user interaction triggers it and I am already on the main thread. ++ungood.
public func closeGraph() {
if Thread.isMainThread {
_closeGraph()
} else {
DispatchQueue.main.sync{_closeGraph()}
}
}
Oops openGraph() throws...
public func openGraph() throws {
do {
if Thread.isMainThread {
try _openGraph()
} else {
try DispatchQueue.main.sync{try _openGraph()}
}
} catch {
throw error
}
}
Is there a better way to this so i don't have to copy paste it everywhere?
You can extract your check to a generic function like this:
public func mainQueue(execute block: () throws -> Void) rethrows {
if Thread.isMainThread {
try block()
} else {
try DispatchQueue.main.sync{ try block() }
}
}
then if your _closeGraph()
function doesn't throw any error, your code will be like this:
public func closeGraph() {
mainQueue(execute: _closeGraph)
}
and if your _closeGraph()
function throws
, your code will be like this:
public func closeGraph() {
do {
try mainQueue(execute: _closeGraph)
} catch {
print(error)
}
}
As you can see you will need to write the handling of the throwing function every time.
Update: If you have a generic error handling in mind, you can hide the do-catch
statement in mainQueue(execute:)
function like this:
public func mainQueue(execute block: () throws -> Void) {
do {
if Thread.isMainThread {
try block()
} else {
try DispatchQueue.main.sync{ try block() }
}
} catch {
print(error)
}
}
then calling this function will be the same whether the _closeGraph()
function is throwing or not:
public func closeGraph() {
mainQueue(execute: _closeGraph)
}