# Leaks using onHover modifier

**URL:** <https://forums.swift.org/t/leaks-using-onhover-modifier/31671>\
**Category:** Using Swift\
**Tags:** off-topic, swiftui\
**Created:** [December 14, 2019, 1:52pm UTC](https://forums.swift.org/t/leaks-using-onhover-modifier/31671 "2019-12-14T13:52:11Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![dehesa](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/dehesa/32/10911_2.png) [@dehesa](https://forums.swift.org/u/dehesa)\
**Post date:** [December 14, 2019, 1:52pm UTC](https://forums.swift.org/t/leaks-using-onhover-modifier/31671/1 "2019-12-14T13:52:11Z")

</div>

TLDR: Using the `onHover` modifier seems to create leaks for any `@ObservedObject` you have defined in the parent SwiftUI view.

### Explanation

I have been developing a mac app with SwiftUI (using Cocoa, not Catalyst). I started to notice that some objects weren't being deinitialized. After some research, I realized that view hierarchies using `onHover` never release their `@ObservedObject` properties.

It is not about creating retain cycles with those objects, you may not use them whatsoever that the objects are still leaking when the view is released.

### Sample Code

You can reproduce the effect by un/commenting the `.onHover` modifier. Please notice that the `state` object is not being used anywhere.

```swift
struct RootView: View {
    @ObservedObject private var state = State()
    
    var body: some View {
        Rectangle()
            .fill(Color.red)
            .frame(width: 100, height: 100)
            .onHover { print("onHover: \($0)") }
            .padding()
    }
}

private final class State: ObservableObject {
    @Published var value: Int = 0
    
    deinit {
        print("State deinitialized")
    }
}

```

I have test this simple view on top of a `NSWindow`, but it doesn't really matter where in your hierarchy is being used.

 ![Wind](https://global.discourse-cdn.com/swift/original/2X/e/ec5fae699bf63e28ef602f5e6fa1da189bc09a2e.png)

## Question

Can someone reproduce it? Is it intended behavior?

---

<div class="post-metadata">

**Author:** ![DevAndArtist](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/devandartist/32/287_2.png) [@DevAndArtist](https://forums.swift.org/u/DevAndArtist)\
**Post date:** [December 14, 2019, 2:04pm UTC](https://forums.swift.org/t/leaks-using-onhover-modifier/31671/2 "2019-12-14T14:04:33Z")

</div>

What is it about that sample code that you expect to eventually deinit the object? It looks all correct to me including the behavior. The object should only be destroyed when `RootView` is recreated from some superview.

---

<div class="post-metadata">

**Author:** ![dehesa](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/dehesa/32/10911_2.png) [@dehesa](https://forums.swift.org/u/dehesa)\
**Post date:** [December 14, 2019, 2:37pm UTC](https://forums.swift.org/t/leaks-using-onhover-modifier/31671/3 "2019-12-14T14:37:58Z")

</div>

When the view is destroyed, I would expect the `ObservableObject` to be destroyed as well. For example, if the window hosting the view is closed and the `NSWindow` memory is reclaimed I expect the `Observable` object to be deinitialized as well. That doesn't occur there. If you close the window, the object lingers in memory.

---

<div class="post-metadata">

**Author:** ![dehesa](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/dehesa/32/10911_2.png) [@dehesa](https://forums.swift.org/u/dehesa)\
**Post date:** [December 15, 2019, 8:38am UTC](https://forums.swift.org/t/leaks-using-onhover-modifier/31671/4 "2019-12-15T08:38:26Z")

</div>

I have created a bug report if anyone is interested: FB7494527

---

<div class="post-metadata">

**Author:** ![swiftuilab](https://avatars.discourse-cdn.com/v4/letter/s/dbc845/32.png) [@swiftuilab](https://forums.swift.org/u/swiftuilab)\
**Post date:** [February 24, 2020, 10:09am UTC](https://forums.swift.org/t/leaks-using-onhover-modifier/31671/5 "2020-02-24T10:09:10Z")

</div>

Having the same problem, although in my case I'm not even using `@ObservedObject`. The issue I think is in `HSHostingView`. The following code illustrates the problem.

When the window is opened a second time, the first `NSHostingView` should deallocate, but it doesn't. I subclassed `NSHostingView` to be able to log calls on `deinit`.

If `onHover` is removed from the code, `NSHostingView` deallocates properly.

```swift
let secondaryWindow = NSWindow(contentRect: NSRect(x: 100, y: 100, width: 100, height: 100), styleMask: [.titled, .closable, .miniaturizable, .resizable, .fullSizeContentView], backing: .buffered, defer: false)

struct ContentView: View {
    var body: some View {
        Button("Open Window") {
            secondaryWindow.isReleasedWhenClosed = false
            secondaryWindow.contentView = CustomNSHostingView(rootView: MySubView())
            secondaryWindow.center()
            secondaryWindow.makeKeyAndOrderFront(nil)
        }
        .frame(maxWidth: .infinity, maxHeight: .infinity)
    }
}

struct MySubView: View {
    var body: some View {
        VStack {
            Text("Hello World")
                .onHover { print("\($0)") }
        }.frame(width: 100, height: 100)
        
    }
}

class CustomNSHostingView<Content>: NSHostingView<Content> where Content : View {
    deinit {
        print("DEINIT")
    }
}

```

---

<div class="post-metadata">

**Author:** ![swiftuilab](https://avatars.discourse-cdn.com/v4/letter/s/dbc845/32.png) [@swiftuilab](https://forums.swift.org/u/swiftuilab)\
**Post date:** [February 24, 2020, 10:09am UTC](https://forums.swift.org/t/leaks-using-onhover-modifier/31671/6 "2020-02-24T10:09:57Z")

</div>

My bug report number: FB7597514

---

<div class="post-metadata">

**Author:** ![aerobounce](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/aerobounce/32/14175_2.png) [@aerobounce](https://forums.swift.org/u/aerobounce)\
**Post date:** [August 11, 2020, 8:13am UTC](https://forums.swift.org/t/leaks-using-onhover-modifier/31671/7 "2020-08-11T08:13:47Z")

</div>

I encountered the bug, too. My situation is much like @dehesa and @swiftuilab.  
Tried to seek a workaround by using only SwiftUI, to no avail.

So I made a NSView wrapper: [GitHub - aerobounce/HoverAwareView: SwiftUI `.onHover` memory leak workaround. NSView wrapper that works just like the modifier.](https://github.com/aerobounce/HoverAwareView)  
Hope this helps.

---

<div class="post-metadata">

**Author:** ![paxos](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/paxos/32/12381_2.png) [@paxos](https://forums.swift.org/u/paxos)\
**Post date:** [August 28, 2020, 9:16pm UTC](https://forums.swift.org/t/leaks-using-onhover-modifier/31671/8 "2020-08-28T21:16:34Z")

</div>

Thanks, this works perfectly!

I encountered this bug today as well after hours of debugging. I think this definitely has something todo with NSHostingView. I really hope this gets fixed soon.
