简体   繁体   English

为什么有弱无力的人? 为什么我们不总是使用弱项?

[英]Why are there weak _and_ unowned? Why can we just not always use weak?

I just read the ARC section in the Swift book and a few other related posts concerning weak and unowned references. 我刚刚阅读了Swift书中ARC部分,以及其他一些有关weak引用和unowned引用的相关文章。

After my readings, I do have a clear understanding on what they are and in what situations each of them are to be used (see also this SO post which gives a great explanation of this). 阅读后,我对它们的用途以及在每种情况下将要使用的每种情况都有清晰的了解(另请参见此SO帖子 ,它对此做了很好的解释)。

However, I fail to understand why Apple even came up with these two solutions? 但是,我不明白为什么苹果公司甚至提出了这两种解决方案? Essentially, from a MM perspective, both come down to not creating a strong reference to the referred object (ie not increasing its retainCount ). 本质上,从MM的角度来看,两者都归结为没有对所引用对象创建强引用(即,不增加其retainCount )。 So, why even bother and provide two MM primitives here? 那么,为什么还要在这里打扰并提供两个MM原语呢?

Now, developers need to understand when to use which of the two, and Apple did a great job in explaining the different scenarios, but they didn't say why . 现在,开发人员需要了解何时使用这两种方法中的哪一种,并且Apple在解释不同情况方面做得很好,但他们没有说明原因 Wouldn't it have been simpler to eg only provide weak so that developers don't need to dig into the docs and understand the different use cases? 例如, 提供weak这样开发人员就无需深入研究文档并了解不同的用例,是否会更简单?

I guess, another way to phrase the question is, why at all should we use unowned , except for Apple telling us so? 我想,用另一种方式来表达这个问题的方式是:除了苹果公司告诉我们的以外,为什么我们应该完全使用unowned At least from a MM standpoint, this wouldn't make a difference and using weak where according to the docs we should use unowned wouldn't create a memory leak?! 至少从MM的角度来看,这没有什么区别,在文档中我们应该使用unowned地方使用weak不会造成内存泄漏?

The difference is in the optionality of variables. 区别在于变量的可选性。 Like Apple says in the Unowned References section of the link you provided: 就像Apple在您提供的链接的“无主引用”部分中所说的那样:

Unlike a weak reference, however, an unowned reference is assumed to always have a value. 但是,与弱引用不同,假定无主引用始终具有值。 Because of this, an unowned reference is always defined as a nonoptional type. 因此,始终将无主引用定义为非可选类型。

The usage of this is more visible in a closure block. 在封闭块中,此用法的使用更为明显。 Here you do not have to use ? 在这里您不必使用? operator or get a reference on the object if you use it inside the closure. 运算符,或者如果在闭包内部使用该对象,则获取该对象的引用。

Instead of writing this: 而不是这样写:

UIView.animateWithDuration(0.2) {
    [weak self]
    () -> Void in
    self?.view.layoutIfNeeded()
}

However, if you can be sure that the reference to self will not be released before the animation and you can simply write unowned and do not have to use the ? 但是,如果可以确定在动画之前不会释放对self的引用,并且可以简单地编写unown,而不必使用? operator or unwrap it with an if let statement: 运算符或使用if let语句将其解包:

UIView.animateWithDuration(0.2) {
    [unowned self]
    () -> Void in
    self.view.layoutIfNeeded()
}

@Kádi's answer about weak variables being optional is correct, but incomplete. @Kádi关于弱变量是可选的答案是正确的,但不完整。

Weak and unowned have a difference in meaning outside of Swift's Optional semantics. 弱和无主在Swift的Optional语义之外的含义有所不同。 A weak reference is more accurately named an auto-zeroing weak reference. 弱引用更准确地称为自动归零弱引用。 The system knows about an object stored in a weak variable, and when the object is deallocated, goes to the extra work to zero out the value. 系统知道存储在弱变量中的对象,并在释放该对象时进行额外的工作以将该值归零。 As a consequence of that, weak variables are optionals in Swift. 作为其中的一个结果是 ,弱变量是斯威夫特选配。

Unowned pointers are not memory managed at all. 无主指针完全不受内存管理。 They are a raw memory pointer that can take any value. 它们是可以采用任何值的原始内存指针。 (They can still be typed to point to a particular type of structure, so they aren't always "raw" in the way a C void pointer is raw.) Unowned pointers are useful for pointing to malloc'ed memory, pointer arithmetic, and the like. (仍然可以键入它们以指向特定类型的结构,因此它们并不总是以C void指针原始的方式“原始”。)无主指针对于指向malloc的内存,指针算术,等等。 Declaring a pointer type as unowned basically tells the compiler "Don't worry about it. I know what I'm doing." 将指针类型声明为unsigned基本上会告诉编译器“不用担心。我知道我在做什么”。 The burden is then on you to make sure the pointer is always valid, before you try to dereference it, and also manage the memory behind the pointer yourself. 在您尝试取消对指针的引用之前,您要负担确保指针始终有效的负担,并自己管理指针后面的内存。

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

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