我正在为CoreData实现一个辅助方法
public func doInMain(_ block: (NSManagedObjectContext) -> Void) {
guard let context = mainQueueContext else { return }
context.performAndWait({
block(context)
})
}
它运作良好,可以这样称呼:
CoreDataManager().doInMain { moc in
// do your fetch request with managed object context
}
但是当我想尝试doInMain
块中的错误时,这很烦人,因为调用函数无法将其抛出。由于集团是nonescaping
,因此应该这样做。
所以我添加了:
public func doInMain(_ block: (NSManagedObjectContext) throws -> Void) rethrows {
guard let context = mainQueueContext else { return }
context.performAndWait({
try block(context)
})
}
但是NSManagedObjectContext.performAndWait不会抛出错误,因此不会编译。
它尝试过:
public func doInMain(_ block: (NSManagedObjectContext) throws -> Void) rethrows {
guard let context = mainQueueContext else { return }
var thrownError: Error?
context.performAndWait({
do { try block(context) }
catch { thrownError = error }
})
if let error = thrownError {
throw error
}
}
但是现在编译器说A function declared 'rethrows' may only throw if its parameter does
我搞砸了吗?有解决方法吗?
谢谢
答案 0 :(得分:1)
并非完全理想,但一种选择是只编写两个重载-一个重载不引发并且本身不引发的闭包,另一个重载引发不引发自身的闭包。
例如:
public func doInMain(_ block: (NSManagedObjectContext) -> Void) {
guard let context = mainQueueContext else { return }
context.performAndWait {
block(context)
}
}
public func doInMain(_ block: (NSManagedObjectContext) throws -> Void) throws {
guard let context = mainQueueContext else { return }
var thrownError: Error?
context.performAndWait {
do {
try block(context)
} catch {
thrownError = error
}
}
if let error = thrownError {
throw error
}
}
请记住,如果需要,您总是可以根据抛出超载实现非抛出超载:
public func doInMain(_ block: (NSManagedObjectContext) -> Void) {
let fn = doInMain as ((NSManagedObjectContext) throws -> Void) throws -> Void
try! fn(block)
}
您应该能够以与单个重新抛出过载大致相同的方式使用这两个过载。