如何在 swift 中创建一个变量,如 newValue(在 setter 中使用)3
How can I create a variable like newValue (used in setter) in swift 3
全部,
我创建了一个像这样接受闭包的方法,
extension NSManagedObject{
class func performOnWorkerContext(_ block:@escaping (_ context:NSManagedObjectContext?) -> ()){
//Create context, Call block() and save context
}
}
我是这样使用这个方法的,('Request'是NSManagedObject类型)。 class方法将修改为:
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 是如何实现的?
这背后的动机是它看起来更优雅,我们不必记住这个闭包中可访问的明显变量。
newValue
是setter中参数的默认名称
计算出的 属性、willSet
属性 观察者,以及
setter 的一个下标方法。它内置于语言中。
在闭包中,您可以命名参数
Request.performAndWaitOnWorkerContext { context in
// Use `context` here
}
或使用shorthand参数名称:
Request.performAndWaitOnWorkerContext {
// Use `[=11=]` here
}
但您不能定义隐式参数名称。
你想要的通常是你希望避免的。在我看来,即使设置者拥有类似
的东西也会更好
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()
}
在更轻松的方面,我会尝试从 public 接口中完全删除 context
并实现您需要的所有可能方法。例如:
entity.performOnBackgroundContext { context in
entity.doMagic()
context.saveDatabase()
}
实际上是:
entity.performOnBackgroundContext {
entity.doMagic()
entity.saveDatabase()
}
虽然扩展 NSManagedObject
或 NSManagedObjectContext
有点警告,但通常会随着复杂性的增加而变坏。还有更好的方法。
全部,
我创建了一个像这样接受闭包的方法,
extension NSManagedObject{
class func performOnWorkerContext(_ block:@escaping (_ context:NSManagedObjectContext?) -> ()){
//Create context, Call block() and save context
}
}
我是这样使用这个方法的,('Request'是NSManagedObject类型)。 class方法将修改为:
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 是如何实现的?
这背后的动机是它看起来更优雅,我们不必记住这个闭包中可访问的明显变量。
newValue
是setter中参数的默认名称
计算出的 属性、willSet
属性 观察者,以及
setter 的一个下标方法。它内置于语言中。
在闭包中,您可以命名参数
Request.performAndWaitOnWorkerContext { context in
// Use `context` here
}
或使用shorthand参数名称:
Request.performAndWaitOnWorkerContext {
// Use `[=11=]` here
}
但您不能定义隐式参数名称。
你想要的通常是你希望避免的。在我看来,即使设置者拥有类似
的东西也会更好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()
}
在更轻松的方面,我会尝试从 public 接口中完全删除 context
并实现您需要的所有可能方法。例如:
entity.performOnBackgroundContext { context in
entity.doMagic()
context.saveDatabase()
}
实际上是:
entity.performOnBackgroundContext {
entity.doMagic()
entity.saveDatabase()
}
虽然扩展 NSManagedObject
或 NSManagedObjectContext
有点警告,但通常会随着复杂性的增加而变坏。还有更好的方法。