如何在 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()
}

虽然扩展 NSManagedObjectNSManagedObjectContext 有点警告,但通常会随着复杂性的增加而变坏。还有更好的方法。