Hi,
Is there any way to declare `rethrows` a function that uses `dispatch_sync`?
For example:
func perform_sync(queue: dispatch_queue_t, block: () throws -> Void) rethrows {
var blockError: ErrorType? = nil
dispatch_sync(queue) {
do {
try block()
} catch {
blockError = error
}
}
if let blockError = blockError {
throw blockError
}
}
The code above has the compiler complain with the message "'rethrows' function may only throw by calling a parameter function".
That's quite unfortunate. If it were possible, one could call this `perform_sync` function without `try`:
try perform_sync(queue) { // try, obviously
try dangerousFunction()
}
perform_sync(queue) { // Look, Ma! No try!
safe_function()
}
Of course, such rethrowing is unsafe: it requires the cooperation of the developer. Well, I'd happily welcome an explicit unsafe construct in the Swift language that would allow me to do that.
Thanks in advance if you have any clue.
I was able to do it in a round about way:
func testperform_sync(){ //call this function to test everything
enum Error : ErrorType {
case Test1;
case Test2;
}
var testfunc = {() -> Void in
print("Inside safe testfunc closure")
}
func rethrow(myerror:ErrorType) throws ->()
{
print("Inside rethrowing function")
throw myerror
}
var myclosure = {() throws -> Void in
let error: Error = Error.Test1
print("Inside unsafe testfunc closure")
throw error
}
func perform_sync(queue: dispatch_queue_t, block: () throws -> Void,
block2:((myerror:ErrorType) throws -> ()) ) rethrows {
var blockError: ErrorType? = nil
dispatch_sync(queue) {
do {
try block()
} catch {
blockError = error
print("This was blocks error: \(blockError)")
}
}
if let blockError = blockError{
print ("Block \(blockError) will be sent to block2")
try block2(myerror: blockError)
}
}
print("TEST WITH SAFE FUNCTION AND PLACEHOLDER PRINT")
perform_sync(dispatch_get_global_queue(Int(QOS_CLASS_USER_INITIATED.rawValue),
0),
block: (testfunc), block2: print)
print("\n\n\nTEST WITH A PRE-DEFINED UNSAFE CLOSURE")
do {try perform_sync(dispatch_get_global_queue(Int(QOS_CLASS_USER_INITIATED.rawValue), 0),
block: myclosure , block2:rethrow)
}catch{
print("Error transferred from block to block2 is \(error)")
}
print("\n\n\nTEST WITH AN UNSAFE CLOSURE")
do {try perform_sync(dispatch_get_global_queue(Int(QOS_CLASS_USER_INITIATED.rawValue), 0),
block: {throw Error.Test2} ,
block2:rethrow)
}catch{
print("Error transferred from block to block2 is \(error)")
}
}