Skip to content

Instantly share code, notes, and snippets.

@zwaldowski
Created September 26, 2016 17:50
Show Gist options
  • Save zwaldowski/2198b4ef8ac5cadc73e635c0036091e2 to your computer and use it in GitHub Desktop.
Save zwaldowski/2198b4ef8ac5cadc73e635c0036091e2 to your computer and use it in GitHub Desktop.
How Stella Got Her @NoEscape Back
// Swift 3 only; `@noescape` only applies to function definitions (not function types) in 2.x.
import CoreData
extension NSManagedObjectContext {
func performAndWaitOrThrow<Return>(_ body: () throws -> Return) rethrows -> Return {
func impl(execute work: () throws -> Return, recover: (Error) throws -> Void) rethrows -> Return {
var result: Return!
var error: Error?
// performAndWait is marked @escaping as of iOS 10.0.
typealias Fn = (() -> Void) -> Void
let performAndWaitNoescape = unsafeBitCast(self.performAndWait, to: Fn.self)
performAndWaitNoescape {
do {
result = try work()
} catch let e {
error = e
}
}
if let error = error {
try recover(error)
}
return result
}
return try impl(execute: body, recover: { throw $0 })
}
}
let context = NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType)
struct SomeError: Error {}
do {
let value: Int = try context.performAndWaitOrThrow {
throw SomeError()
}
print(value)
} catch {
print(error)
}
@bm-w
Copy link

bm-w commented Nov 9, 2016

Any idea whether this was an oversight during the great renamification? Or is it intentionally @escaping? They’ve been so nicely diligent providing DispatchQueue’s func sync<T>(execute: () throws -> T) rethrows -> T. Have you reported this as a bug?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment