Using Lazy Initialization, how do we reset the var?

  private lazy var xpcConnection : NSXPCConnection = {
      let aConnection = NSXPCConnection(machServiceName: oppositeInformantBundleID, options: NSXPCConnectionOptions(rawValue: 0))
      aConnection.remoteObjectInterface = NSXPCInterface(withProtocol: InformantHelperXPCProtocol.self)
      aConnection.interruptionHandler = {
            DDLogVerbose("XPC Connection to \(oppositeInformantBundleID) has been interrupted.")
      }

      aConnection.invalidationHandler = {
            DDLogVerbose("XPC Connection to \(oppositeInformantBundleID) has been invalidated.")
      }

      aConnection.resume()

      DDLogVerbose("XPC Connection to \(oppositeInformantBundleID) has been created")

      return aConnection
  }()


Given a lazy instantiation - I need to reset the connection variable in the invalidationHandler. I'm still learning the ins and outs of Swift2, so I'll be frank that I'm a bit hazy here.


What I'd like to happen is that in my invalidationHandler, I can reset xpcConnection back to a lazy nil state so that the next time xpcConnection is called the instantiation code above is run again.

Accepted Answer

It's my understanding that a lazy variable can never change after its been called.

What you probably want is a private cached variable and change xpcConnect to be a calulated properted. So pretty much the old boring way of doing things:


private var xpcConnectionCache:NSXPConnection?
var xpcConnect:NSXPConnection {
     // check to see if xpcConnectionCache is defined, if so return it, otherwise generate it
     // when the invalidationHandler runs, reset xpcConnectionCache to nil
}

That's what I ended up doing…I did read the docs and they were pointing me that way, but I wanted to be sure. Sometimes I see some interesting stuff that I would never have thought of around here.

If you wanted things to be a bit nicer you could make your own Lazy implementation.

(Please note I have not tested this code, I just wrote it in the response, so it might take a bit of tweaking)


public class Lazy<T> {
     // need a generator that also has the ability to invalidate the value it created by calling reset
     private let generator: ( (reset:(()->())) ->T )?
     private var cached:T?
     init(_ generator:(()->T)) {
          self.generator = generator
     }
     func reset() {
          self.cached = nil
     }
     var value:T {
          if let cached = cached {
               return cached
          } else {
               let generated = generator() { [weak self] self.reset() }
               self.cached = generated
               return generated
          }
     }
}

let xpcConnection = Lazy<NSXPCConnection>(){ reset in
     // ....
     aConnection.invalidationHandler = { reset() }
     // ....
     return aConnection
}
Using Lazy Initialization, how do we reset the var?
 
 
Q