Does this lazy property's initialiser generate a strong reference cycle?

Does the following Contact class in the code below generate strong reference cycle if the lazy property is not accessed?

When I use the "Debug Memory Graph" feature of Xcode, I cannot find any leaks when the lazily initialised property is either accessed or ignored. Is this correct?

What's the recommended practice for referencing self when initialising variables and property with functions?


import Foundation

class Contact {

let identifier = UUID().uuidString

lazy var photo: Data = {
        // Get the URL to the /path/to/app/sandbox/Caches folder.
        guard let folderURL = try? FileManager.default.url(for: .cachesDirectory, in: .userDomainMask, appropriateFor: nil, create: true) else {
            return Data()
        // Get the URL to a specific png in the Caches folder.
        let fileURL = folderURL.appendingPathComponent(self.identifier).appendingPathExtension("png")
        if let data = try? Data(contentsOf: fileURL) {
            return data
        // Failing this, return an empty data instance.
        return Data()

// When memory used by this function is cleared, I would expect contact to be deinitialised, because the property has been accessed and therefore initialised.
func lazyVarAccessed() {
let contact = Contact()
let data =

// The photo property is not accessed and by virtue of being lazy, not initialised. Is contact deinitialised when the memory used by this function is cleared?
func lazyVarIgnored() {
let contact = Contact()


To which question do you refer?


If so, how do you know?

I was answering the title question. A lazy property (including its initializer) is part of an instance. It will not be callable once the instance goes out of scope. Think of self in that closure as being implicitly unowned because we know it can't outlive self.

Thanks for the follow up! While it is easy to think that, there's no obvious reason to think it because that'd mean an initialisation closure for a lazy property had undocumented memory/reference semantics when compared to every other occurrence of a closure. It seems there's credence to think otherwise.

Oh, you are right. My answer was not very accurate. Let me try again:

You have () at the end of the closure. For a normal property, the closure would run immediately upon init and would be discarded (would not escape).

The same logic still holds: It is discardable. The compiler is smart enough to discard it at deinit regardless of whether it has actually been called or not.