因为不知道completion
是否为@escaping
(例如,如果它被保留),所以不可能说出A.someFunctionA
。对于其余的答案,我将假定它是@escaping
。
Swift需要确保运行时安全,并将保留未来可能需要的任何对象,在这种情况下,通过强烈参考self
(因为self
是封闭内部使用的唯一变量)。
在这种情况下没有参考周期。这是因为instanceA
不被保留,所以A => B,但乙!=> A.
但是,如果instanceA
被B
(假设您创建一个instanceA: A
属性,并将其设置),那么你将有一个保留保留周期。
为了解决这个问题,您可以在闭包中创建变量weak
或unowned
。他们都做同样的事情,但为你提供稍微不同的类型。它们都有一个弱引用,这意味着instanceA
将不会增加B
实例的引用计数;如果B
被解除分配,并且没有其他参考,instanceA
也被释放。
当使用[weak self]
self
是optional
,例如, self: B?
。然而,[unowned self]
明确展开,例如, self: B!
。这意味着如果关闭被调用,并且self
是nil
您的程序将崩溃。这就是为什么仅当使用unowned
时,如果确定释放B
也会释放A
,这一点很重要。有几种情况,其中unowned
是安全的,例如,在创建闭包并将其存储在创建它的同一个对象上的情况下,但是有更多的细微差别。
如果不确定,请使用weak
!
谢谢你的回答!只是为了确认,所以当我在类B的函数内部创建一个instanceA:A时,它仅在函数的上下文中考虑,而不是该类的引用?做出强有力的参考的唯一方法是让instanceA:A类的属性?还有一个问题,如果我不把@escaping,封闭不保留自我? – Arrabidas92
是的,在这种情况下'instanceA'只保存在内存中,直到它不再被引用到任何地方,这是'makeAclosure'的一次执行完成。是的,停止'instanceA'被释放的唯一方法就是强烈引用它,比如将它设置为'B'的属性。如果你不放'@ escaping',编译器将不允许你存储传入的闭包。不用'@ escaping'开始,等待编译器发出抱怨! –