English 中文(简体)
我们总是在快速关闭时使用[非自有的]。
原标题:Shall we always use [unowned self] inside closure in Swift
  • 时间:2014-06-20 05:11:50
  •  标签:
  • swift
最佳回答

您不希望使用<条码>[自有]。 有时,你们想要关闭是为了自我控制,以确保封锁在要求关闭时仍然前后。

Example: Making an asynchronous network request

如果您提出星座网络要求,请您do在申请完成时要求关闭<代码>自封/代码>。 否则,该物体可能已经停用,但你仍然希望能够处理完成申请。

When to use unowned self or weak self

The only time where you really want to use [unowned self] or [weak self] is when you would create a strong reference cycle. 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.

在关闭的具体情况下,你必须认识到,在封闭状态中提及的任何变数都“拥有”。 只要封锁环绕,这些物体就得到保证。 停止这种所有权的唯一途径是填写<代码>[非自有]或[weak self]。 因此,如果某个阶层拥有关闭权,而关闭则能有力地提及这一类别,那么,在关闭和关闭类别之间,你就有一个强有力的参照周期。 这也包括,如果该阶级拥有一些拥有封锁的物品。

Specifically in the example from the video

In the example on the slide, TempNotifier owns the closure through the onChange member variable. If they did not declare self as unowned, the closure would also own self creating a strong reference cycle.

Difference between unowned and weak

The difference between unowned and weak is that weak is declared as an Optional while unowned is not. By declaring it weak you get to handle the case that it might be nil inside the closure at some point. If you try to access an unowned variable that happens to be nil, it will crash the whole program. So only use unowned when you are positive that variable will always be around while the closure is around

问题回答

Update 11/2016

我撰写了一篇关于扩大这一答案的文章(见ARC所做的事),在here

Original answer

先前的答复并没有真正地就何时使用一种手段以及为什么,让我补充几点。

未掌握或讨论不力,就成了变数的/lifetime和其中提及的封闭问题。

“swiftuna

Scenarios

您可以有两种可能的设想:

  1. 关闭时间与变数的寿命相同,因此,只有在变数达到<>>之前,方可关闭。 变数和封闭寿命相同。 在这种情况下,你应宣布这一提法为un Owner。 常见的例子有:[非自有],用于许多例子,说明在父母中做事情的小结关,在任何其他地方都没有提到父母。

  2. 封闭寿命独立于变数之一,在变数无法再达到时,仍然可以提及封闭。 在这种情况下,你应宣布这一提法为wak,并在使用该词之前加以核实(登革部队不失控)。 这方面的一个共同例子是<代码>[我们有代表],你可以在某些例子中看到,封闭是指完全无关的(终身)代表反对。

Actual Usage

So, which will/should you actually use most of the times?

Quoting Joe Groff from twitter:

独有财产较快,可以互换和不选择。

www.un.org/Depts/DGACM/index_spanish.htm 如果你不需要软弱,不使用。

页: 1

我认为,我要特别为一位观点控制者补充一些具体例子。 很多解释,不仅在Stack Overflow上,也确实是好的,但我以真实的世界实例更好地工作(“drewag”在这方面有一个良好的开端):

  • If you have a closure to handle a response from a network requests use weak, because they are long lived. The view controller could close before the request completes so self no longer points to a valid object when the closure is called.
  • 如果你关闭,处理在纽特发生的事件。 可在<条码>内自有<>条/条码>上查阅,因为一俟电源控制器停用, but子和从<条码>上可指的任何其他物品。 同时消失。 封闭区也将同时关闭。

    class MyViewController: UIViewController {
          @IBOutlet weak var myButton: UIButton!
          let networkManager = NetworkManager()
          let buttonPressClosure: () -> Void // closure must be held in this class. 
    
          override func viewDidLoad() {
              // use unowned here
              buttonPressClosure = { [unowned self] in
                  self.changeDisplayViewMode() // won t happen after vc closes. 
              }
              // use weak here
              networkManager.fetch(query: query) { [weak self] (results, error) in
                  self?.updateUI() // could be called any time after vc closes
              }
          }
          @IBAction func buttonPress(self: Any) {
             buttonPressClosure()
          }
    
          // rest of class below.
     }
    

http://www.ohchr.org。 可在封闭式使用[weak self]上打消。

如果自封,在封闭式使用中永远不会是零。

页: 1

Here is brilliant quotes from Apple Developer Forums described delicious details:

unowned vs unowned(safe) vs unowned(unsafe)

unowned(safe) is a non-owning reference that asserts on access that the object is still alive. It s sort of like a weak optional reference that s implicitly unwrapped with x! every time it s accessed. unowned(unsafe) is like __unsafe_unretained in ARC—it s a non-owning reference, but there s no runtime check that the object is still alive on access, so dangling references will reach into garbage memory. unowned is always a synonym for unowned(safe) currently, but the intent is that it will be optimized to unowned(unsafe) in -Ofast builds when runtime checks are disabled.

unowned vs weak

unowned actually uses a much simpler implementation than weak. Native Swift objects carry two reference counts, and unowned references bump the unowned reference count instead of the strong reference count. The object is deinitialized when its strong reference count reaches zero, but it isn t actually deallocated until the unowned reference count also hits zero. This causes the memory to be held onto slightly longer when there are unowned references, but that isn t usually a problem when unowned is used because the related objects should have near-equal lifetimes anyway, and it s much simpler and lower-overhead than the side-table based implementation used for zeroing weak references.

<>Update: http://stackoverflow.com/a/34862353/496389“weak 内部使用与<代码>un Owner相同的机制。 因此,这一比较是不正确的,因为它比较了目标Cweak和快速unonwed

Reasons

What is the purpose of keeping the memory alive after owning references reach 0? What happens if code attempts to do something with the object using an unowned reference after it is deinitialized?

The memory is kept alive so that its retain counts are still available. This way, when someone attempts to retain a strong reference to the unowned object, the runtime can check that the strong reference count is greater than zero in order to ensure that it is safe to retain the object.

What happens to owning or unowned references held by the object? Is their lifetime decoupled from the object when it is deinitialized or is their memory also retained until the object is deallocated after the last unowned reference is released?

All resources owned by the object are released as soon as the object s last strong reference is released, and its deinit is run. Unowned references only keep the memory alive—aside from the header with the reference counts, its contents is junk.

Excited, huh?

There are some great answers here. But recent changes to how Swift implements weak references should change everyone s weak self vs. unowned self usage decisions. Previously, if you needed the best performance using unowned self was superior to weak self, as long as you could be certain that self would never be nil, because accessing unowned self is much faster than accessing weak self.

但是,迈克·阿什记录到,快速度如何更新了弱小var的使用,以使用旁证,这如何大大改善自我表现的弱点。

rel=“noreferer” https://mikeash.com/pyblog/friday-qa-2017-09-22-swift-4-weak-viss.html

既然对软弱无力的自我行为没有重大的业绩惩罚,我认为我们应当不肯利用它。 软弱的自我好处是,它是一种可选择的,使撰写更正确的守则更为容易,它从根本上说,迅速的理由是这样一种伟大的语言。 你也许会认为,你知道哪些情况对使用无人拥有的自我保护是安全的,但我审查其他开发商法典的许多内容的经验却最多。 在无人自有的自有地进行办公的情况下,我发现固定的坠毁物,通常情况下,在控制器被分配后,背景已经完好。

弹道和坠机是方案规划最耗时、痛苦和最昂贵的部分。 最好写出正确的法典,避免。 我建议,这条规则绝不是强迫不舒服的选择性做法,永远不会使用不自有的自我,而不是软弱的自我。 你们赢得了任何损失,因为部队失控,而无主的自我实际上是安全的。 但是,你从去除难发现和破碎的坠毁和ug而得很多。

According to Apple-doc

  • Weak references are always of an optional type, and automatically become nil when the instance they reference is deallocated.

  • If the captured reference will never become nil, it should always be captured as an unowned reference, rather than a weak reference

例:

    // if my response can nil use  [weak self]
      resource.request().onComplete { [weak self] response in
      guard let strongSelf = self else {
        return
      }
      let model = strongSelf.updateModel(response)
      strongSelf.updateUI(model)
     }

    // Only use [unowned self] unowned if guarantees that response never nil  
      resource.request().onComplete { [unowned self] response in
      let model = self.updateModel(response)
      self.updateUI(model)
     }

unowned is similar to weak they don t a retained object from being destroyed, but weak variables turned to nil when the object its a reference to no longer exists, which we can handle with the normal checking of nils, unowned will just become garbage, you can t tell they are no longer garbage and using them will crash. The problem with weak is if an object has references to it by weak variables, when its destroyed, it has to go through every reference to it and set that variable to nil, this clearly is going to be expensive, using unowned instead is going just crash and finding this kind of bug is going to be difficult. One place to use unowned is if you are creating some carefully contained datatype, which has a clear interface, and its internals are not directly accessible, for you implementation it may be useful to have lots of circular references but that are self contained, you can used unowned references to let you break those circular references, with out the expense of weak variables, for example you may have a node tree, and each node needs has to have a reference to its parent, deleting a node is going to delete all its children, so there is no point of all the children having to have all there parent references set to nil.

If none of the above makes sense:

http://www.ohchr.org。

Just like an implicitly unwrapped optional, If you can guarantee that the reference will not be nil at its point of use, use unowned. If not, then you should be using weak.

<>Explanation:

我在以下网址检索到:weak un OwnerLink。 从我收集到的,没有自有的自有的“:t是无能为力的,而没有自有的自有可能会导致点 d。

"UNOWNED Weak and unowned references behave similarly but are NOT the same."

Unowned references, like weak references, do not increase the retain count of the object being referred. However, in Swift, an unowned reference has the added benefit of not being an Optional. This makes them easier to manage rather than resorting to using optional binding. This is not unlike Implicitly Unwrapped Optionals . In addition, unowned references are non-zeroing. This means that when the object is deallocated, it does not zero out the pointer. This means that use of unowned references can, in some cases, lead to dangling pointers. For you nerds out there that remember the Objective-C days like I do, unowned references map to unsafe_unretained references.

这是它几乎没有混淆之处。

软弱和无主参考资料都不会增加。

它们既可用于打破保留周期。 因此,我们何时使用这些工具?

According to Apple s docs:

“凡提到“valid时,凡提及该字,在其一生中就成为无。 反之,如果你知道,一旦在初始阶段确定这一提法,就永远不会没有提及。 ......

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.

        let storyboard = UIStoryboard(name: "Main", bundle: nil)
        let controller = storyboard.instantiateViewController(withIdentifier: "AnotherViewController")
        self.navigationController?.pushViewController(controller, animated: true)

    }

}



import UIKit
class AnotherViewController: UIViewController {

    var name : String!

    deinit {
        print("Deint AnotherViewController")
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        print(CFGetRetainCount(self))

        /*
            When you test please comment out or vice versa

         */

//        // Should not use unowned here. Because unowned is used where not deallocated. or gurranted object alive. If you immediate click back button app will crash here. Though there will no retain cycles
//        clouser(string: "") { [unowned self] (boolValue)  in
//            self.name = "some"
//        }
//


//
//        // There will be a retain cycle. because viewcontroller has a strong refference to this clouser and as well as clouser (self.name) has a strong refferennce to the viewcontroller. Deint AnotherViewController will not print
//        clouser(string: "") { (boolValue)  in
//            self.name = "some"
//        }
//
//


//        // no retain cycle here. because viewcontroller has a strong refference to this clouser. But clouser (self.name) has a weak refferennce to the viewcontroller. Deint AnotherViewController will  print. As we forcefully made viewcontroller weak so its now optional type. migh be nil. and we added a ? (self?)
//
//        clouser(string: "") { [weak self] (boolValue)  in
//            self?.name = "some"
//        }


        // no retain cycle here. because viewcontroller has a strong refference to this clouser. But clouser nos refference to the viewcontroller. Deint AnotherViewController will  print. As we forcefully made viewcontroller weak so its now optional type. migh be nil. and we added a ? (self?)

        clouser(string: "") {  (boolValue)  in
            print("some")
            print(CFGetRetainCount(self))

        }

    }


    func clouser(string: String, completion: @escaping (Bool) -> ()) {
        // some heavy task
        DispatchQueue.main.asyncAfter(deadline: .now() + 5.0) {
            completion(true)
        }

    }

}

If you do not sure about [unowned self] then use [weak self]

您提到,为了避免循环提及,你不想作强有力的参考。 因此,在最后强烈提及物体被拆除的某个时候,该物体本身就被拆除。

What happens to other non-strong references? Obviously they don’t refer to that object anymore, which is problematic. There are two kinds of ways to handle this:

  1. Weak reference. When the last strong reference to an object goes away, all weak references are set to nil, so a developer can check if the referenced object is there anymore. Quite obviously a weak reference must be an optional, otherwise it couldn’t be set to nil. The strategy to use a weak reference: You write “if let ref = weakref”. Either the reference was still there, and since you just assigned it to a strong reference, it will remain until the end of the “if let”. If you don’t do it this way then you may access the same weak reference twice, and it may be (unexpectedly) not nil on the first access, but nil on the second.

  2. 你是一纸空文。 如果目标消失,没有人会告诉你。 它将看一看你在提到物体消失时是否参考了。 只有当你100%地确信被提及物体不能提早时,你才能使用。

Use unowned if you have measured that it is faster, and when you are 100% that you don’t use the rubbish when the object is gone.

您可自封使用un Ownerweak,摆脱保留周期。

主要的区别是,当被援引的案件的寿命比援引案件或财产短时,你使用[weak Self],如果被援引的案件的寿命与援引案件/财产的时间相同或更多,则使用[un Owner]

例如,该守则

class TempNotifier {
    var onChange: (Int) -> Void = {_ in }
    var currentTemp = 72
    init() {
        onChange = { [unowned self] temp in
        self.currentTemp = temp
        }
    }
}

我们可以保证,对Change的封锁不会超出宣布的班级。 在TempNotifier公司进行交易后,你可以同意不采用这一死板方法。

另一方面,在网络电话方法中,特别是如果你使用@escaping ends,那么它的高度建议是,你不应使用[不自有的],因为这种封锁超出了班级的范围,甚至在班级办案时也可以说。 在这些情况下,最好使用





相关问题
SwiftUI: How do I position a button x points above a sheet?

I am trying to recreate a Maps-style UI with a persistent bottom sheet and controls fixed above. Apple Maps UI with controls above ☝️ Example here, the "Look Around" binoculars button and ...

BraintreeDropIn deprecated functions error

I m getting this error on the latest release of BraintreeDropIn, I really don t get it since based on the patch notes, this should ve been addressed already, I have already tried cleaning derived data,...

how to limit zoom level in map swift ui?

how to limit zoom level in map swift ui i have map and need to make zoom level limited Map(coordinateRegion: $region,annotationItems: viewModel.nearbyGyms) { item in ...

UIImageView - How to get the file name of the image assigned?

Is it possible to read the name of an UIImageView s UIImage that s presently stored in the UIImageView? I was hoping you could do something kind of like this, but haven t figured it out. NSString *...