所有
我创建了一个像这样的闭包的方法,
extension NSManagedObject{
class func performOnWorkerContext(_ block:@escaping (_ context:NSManagedObjectContext?) -> ()){
//Create context, Call block() and save context
}
}
我使用这样的方法,('Request'的类型为NSManagedObject)。类方法将被修改为:
extension NSManagedObject{
class func performOnWorkerContext(_ block: @escaping () ->()) {
//Create context, Call block() and save context
}
}
Request.performAndWaitOnWorkerContext { context in
//Use the 'context' here
}
现在,我的问题是如何使用这种方法,
Request.performAndWaitOnWorkerContext {
//Use 'context' here
}
这里我想使用变量'context'(我不知道如何,这是问题)。当我们在swift
中使用setter时,我已经看到了类似的实现实施例。如果我使用
var temp: Int {
set {
print(newValue) // Here 'newValue' is automatically available
}
get {}
}
我想要实现这样的东西,请建议它是否可行或者swift中的setter如何做到这一点?
这背后的动机是它看起来更优雅,我们不必记住在这个闭包中可以访问的明显变量。
答案 0 :(得分:0)
newValue
是setter中参数的默认名称
计算属性,willSet
属性观察者,以及
下标方法的setter。它内置于语言中。
在闭包中,您可以命名参数
Request.performAndWaitOnWorkerContext { context in
// Use `context` here
}
或使用速记参数名称:
Request.performAndWaitOnWorkerContext {
// Use `$0` here
}
但您无法定义隐式参数名称。
答案 1 :(得分:0)
你想要的是你想要避免的一般事物。在我看来,即使在设置者有类似
的情况下也会更好set { newValue in
_value = newValue
}
这样做的主要原因是命名时很容易出现冲突。请考虑以下代码:
let context = mainThreadContext
...
entity.performOnBackgroundContext { context in
context.saveDatabase()
}
你可以看到2个上下文有点冲突,我们可能不会同时使用它们。但在这种情况下,只需简单地重命名一个:
let context = mainThreadContext
...
entity.performOnBackgroundContext { backgroundContext in
backgroundContext.saveDatabase()
DispatchQueue.main.async { context.merge() }
}
虽然在你的情况下如果参数被完全删除你就没有这种力量,更令人担心的是,看到这段代码的其他人将完全混淆以下情况中的两个上下文不是同一个对象:
let context = mainThreadContext
...
entity.performOnBackgroundContext {
context.saveDatabase()
}
在较轻的一面,我会尝试从公共接口中完全删除context
并实现您需要的所有可能方法。例如:
entity.performOnBackgroundContext { context in
entity.doMagic()
context.saveDatabase()
}
实际上是:
entity.performOnBackgroundContext {
entity.doMagic()
entity.saveDatabase()
}
虽然扩展NSManagedObject
或NSManagedObjectContext
,但随着复杂程度的增加,通常会出现一些警告。有更好的方法。