以下是示例:
var completionHandlers: [() -> Void] = []
func someFunctionWithEscapingClosure(completionHandler: @escaping () -> Void) {
completionHandlers.append(completionHandler)
}
SomeClass {
var x = 10
func doSomething() {
someFunctionWithEscapingClosure { self.x = 100 }
}
}
let instance = SomeClass()
instance.doSomething()
当调用instance.doSomething()时,它会将闭包附加到数组completionHandlers.It变为:
var completionHandlers:= [{self.x = 100} ]
调用completionHandlers.first?()
时,会调用{ self.x = 100 }
,然后x变为100。
completionHandlers.first?()
print(instance.x)
// Prints "100"
我的问题是数组中的{ self.x = 100 }
{ instance.x = 100 }
?我的意思是self
引用对象实例,即使我们在实例类之外使用它?
谢谢!
答案 0 :(得分:0)
在评论中,您要问:
在实例类中,
inst
等于实例属性candidate
。当我们调用closure时,在实例类之外,self.x
仍然是实例属性x
?
是。闭包内的self.x
引用创建闭包的对象,而不是最终调用闭包的对象(可能更晚)。因此,如果对象x
将引用self
的闭包传递给另一个对象A
,当self.x
调用该闭包时,B
仍会引用'是B
的{{1}}财产,而不是self.x
。
在回答原始问题时,是的,您可以参考您想要的任何实例。它不一定是A
。
然而,你用这个问题说出的抽象方式让我有点怀疑。这个问题"我可以更新任何其他实例"介绍了一些淡淡的代码味道。闭包模式的优点是你让对象启动一些动作来提供一个闭包,该闭包指示当另一个对象完成某个任务时,第一个对象应该发生什么,保持一切顺利,松散耦合。
但是当你开始更新其他不相关的对象时,事情又开始变得更加紧密。这一切都归结为x
是什么以及它与创建闭包的B
有什么关系。
但是,简而言之,是的,您可以更新self
以外的项目的属性或调用方法,但我们需要更好地了解这些不同的对象在评论它是否是'在这种情况下是不是一个好主意。