Uploaded image for project: 'Swift'
  1. Swift
  2. SR-5816

KeyPath-based KVO: Unable to stop observing owned object on deinit

    XMLWordPrintable

    Details

    • Type: Bug
    • Status: Open
    • Priority: Medium
    • Resolution: Unresolved
    • Component/s: Foundation
    • Labels:
      None
    • Environment:

      Version 9.0 beta 6 (9M214v)

      Description

      MyHostObject owns MyObject and observes changes of it's value: 

       

      import Foundation
      
      class MyObject: NSObject {
        @objc dynamic var value: Int = 0
      }
      
      class MyHostObject: NSObject {
        @objc dynamic let myObject = MyObject()
        var _observation: NSKeyValueObservation?
      
        override init() {
          super.init()
          _observation = observe(\.myObject.value, options: [.new]) { (myObject, change) in
            print("value changed to \(change.newValue!)")
          }
        }
      
        deinit {
          // `myObject` is in Limbo right now, but I can still call it's methods and, hopefully, remove observation
          _observation?.invalidate()
          _observation = nil
        }
      }
      
      var myHostObject: MyHostObject? = MyHostObject()
      myHostObject = nil // crashing here with:
      // *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'An instance 0x101c10290 of class issue_NSKeyValueObservation.MyHostObject was deallocated while key value observers were still registered with it. Current observation info: <NSKeyValueObservationInfo 0x101c14ed0> (
      <NSKeyValueObservance 0x101c14c20: Observer: 0x101c115f0, Key path: myObject.value, Options: <New: YES, Old: NO, Prior: NO> Context: 0x0, Property: 0x101c129b0>
      )'
      

       

      With Objective-C equivalent, MyHostObject would still be able to remove observation from myObject.

      This is happening because NSKeyValueObservation holds a weak reference to an object. That weak reference turns to nil too soon. My suggestion is to use unowned or Unmanaged<MyObject> reference.

       

        Attachments

          Activity

            People

            • Assignee:
              Unassigned
              Reporter:
              amironov Anton Mironov
            • Votes:
              7 Vote for this issue
              Watchers:
              9 Start watching this issue

              Dates

              • Created:
                Updated: