简体   繁体   English

为什么在你依赖自己的地方指定[无主自我]?

[英]Why specify [unowned self] in blocks where you depend on self being there?

I want self to be non-nil and I'm sure it will be, during the blocks execution. 在块执行期间,我希望自己是非零的,我确信它会是非零的。 So why explicitly specify [unowned self] ? 那么为什么要明确指定[无主自我]?

object.executeBlock {
    date = self.lastModified
}

vs VS

object.executeBlock { [unowned self] in
    date = self.lastModified
}

Edit: Well i'm getting down votes so let's try again. 编辑:嗯,我正在投票,所以让我们再试一次。 Q: Let's say I have a problem. 问:假设我有问题。 That problem is that I would like to prevent a reference cycle. 那个问题是我想阻止参考周期。 I have two options. 我有两个选择。 I could use [unowned self] or I could use [weak self]. 我可以使用[无主的自我]或者我可以使用[弱自我]。 My question therefore, is this: from these two options, why would I choose [unowned self] ? 因此,我的问题是:从这两个选项中,为什么我会选择[无主自我]? Why not choose [weak self] everytime ? 为什么不每次选择[弱自我]?

"The Language Guide claims you should use unowned if the closure and containing object reference each other and will be destroyed at the same time. Presumably that's to avoid the cost of safely nil'ing out a weak reference in an object that's about to dealloc anyway." “语言指南声称如果封闭物和包含物体相互引用并且将同时被摧毁,你应该使用无主物。可能这是为了避免安全地在一个即将释放的物体中的弱引用“。

http://www.russbishop.net/swift-capture-lists http://www.russbishop.net/swift-capture-lists

So [unowned self] makes self an an implicitly unwrapped optional, for the convenience of not unwrapping it yourself, at the risk of a crash if of course it is actually nil. 所以[无主的自我]使自我成为一个隐含的未包装的选项,为了方便自己不打开它,冒着崩溃的风险,当然它实际上是零。

The only time where you really want to use [unowned self] or [weak self] is when you would create a strong reference cycle. 您真正想要使用[unowned self][weak self]的唯一时间是您创建一个强大的参考周期。 A strong reference cycle is when there is a loop of ownership where objects end up owning each other (maybe through a third party) and therefore they will never be deallocated because they are both ensuring that each other stick around. 一个强大的参考周期是当存在一个所有权循环,其中对象最终彼此拥有(可能通过第三方),因此它们将永远不会被释放,因为它们都确保彼此坚持。

Do you have a strong reference cycle there? 你有一个强大的参考周期吗?

I answered this elsewhere. 我在别处回答。 Here's the Cliff notes: 这是克里夫的笔记:

If self could be nil in the closure use [weak self]. 如果封闭使用自我可能是零[弱自我]。

If self will never be nil in the closure use [unowned self]. 如果自我永远不会在闭包中使用[无主自我]。

If it's crashing when you use [unowned self] I would guess that self is nil at some point in that closure, which is why you had to go with [weak self] instead. 如果你在使用[无主自我]时崩溃了,我猜在封闭的某个时刻自我是零,这就是为什么你不得不选择[弱自我]。

I really liked the whole section from the manual on using strong, weak, and unowned in closures: 我非常喜欢手册中有关使用强,弱和无封闭的手册的整个部分:

https://developer.apple.com/library/ios/documentation/swift/conceptual/swift_programming_language/AutomaticReferenceCounting.html https://developer.apple.com/library/ios/documentation/swift/conceptual/swift_programming_language/AutomaticReferenceCounting.html

Why [unowned self]? 为什么[无主自我]? self points to object, object has executeBlock, and executeBlock points back to self, creating a memory cycle. self指向object,object指向executeBlock,executeBlock指向self,创建一个内存循环。

However when you say [unowned self]: the system will not keep self in memory in order to to make the closure work. 但是当你说[unowned self]时:系统不会将自己保留在内存中以使闭包起作用。 it will assume that self is always there when the closure is executed. 它将假设在执行闭包时self始终存在。 If not for some reason, there won't be undefined behavior or anything like that but your app will crash as it is a runtime error. 如果不是出于某种原因,将不会有未定义的行为或类似的东西,但您的应用程序将崩溃,因为它是运行时错误。

This is how it was explained by Paul Hegarty, stanford iOS dev teacher. 这就是stanford iOS开发老师Paul Hegarty所解释的。

In a situation where self could conceivably be nil at the time it's used in the closure, you're compelled to use weak semantics (or risk a crash). 在闭包中使用self可以想象为nil的情况下,你被迫使用weak语义(或冒着崩溃的风险)。

In a case where you can reason that self will never be nil , you can choose to specify either: "choose" in the sense that both are correct and will work. 在你可以推断self永远不会是nil ,你可以选择指定:“选择”,因为两者都是正确的并且会起作用。 Arguably one could be considered "more correct" than the other, in the sense that both semantics satisfy the requirements but one is more specific. 可以说,一个可以被认为比另一个更“正确”,因为两个语义都满足要求,但一个更具体。

Two reasons you might want to specified unowned instead of self : 您可能希望指定unowned而不是self两个原因:

  • Convenience 方便
  • Documentation 文档

An unowned reference will be more convenient to use because it doesn't need to be unwrapped. unowned参考将更方便使用,因为它不需要打开。 It may also be more efficient, since the compiler may not have to produce as much cleanup code for safe deallocation. 它也可能更有效,因为编译器可能不必为安全释放生成尽可能多的清理代码。

In terms of documentation, you're making a kind of assertion about something your program believes to be true. 在文档方面,你会对你的程序认为是真实的东西做出某种断言。 If that assumption (assuming it was valid) is violated, you may like to find out about it in the form of a crash. 如果违反了该假设(假设它是有效的),您可能希望以崩溃的形式找到它。

Subsequently, this may also make usage of the variable less exhausting: you think about it and document your reasoning that it must always exist up front, and then each time you use it, you don't have to expend further mental energy wondering "what do I do if this isn't here?". 随后,这也可能使变量的使用减少耗尽:你想一想并记录你的理由,它必须始终存在,然后每次你使用它,你不必花费更多的精神能量想知道“什么如果不在这里我该怎么办?“

Arguably, using a let binding or guard statement also achieves the latter. 可以说,使用let绑定或guard语句也可以实现后者。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM