dmytro-anokhin / url-image

AsyncImage before iOS 15. Lightweight, pure SwiftUI Image view, that displays an image downloaded from URL, with auxiliary views and local cache.
MIT License
1.1k stars 96 forks source link

Crashing: URLImage in tvOS NavigationLink #98

Closed NoahKamara closed 3 years ago

NoahKamara commented 3 years ago

Summary and/or background Whenever I try to use URLImage inside a NavigationLink in tvOS I get the following errors. (as soon as I focus the navigationLink)

It seems to be the same issue @abbasmousavi had but it wasn't addressed. Attempted to read an unowned reference but the object was already deallocated I am using 2.0.0alpha.1

Screen Shot 2020-10-12 at 1 05 41 AM

Originally posted by @abbasmousavi in https://github.com/dmytro-anokhin/url-image/issues/84#issuecomment-706790028

OS and what device you are using

Version of URLImage library I've tested it with 2.1.1 and 2.0.0

What you expected would happen The navigationLink element should go into focussed mode

What actually happens The App Crashes.

Fatal error: Attempted to read an unowned reference but the object was already deallocated2020-10-28 23:11:54.597926+0100 ABJC (ATV)[34705:1554277] Fatal error: Attempted to read an unowned reference but the object was already deallocated
Fatal error: Attempted to read an unowned reference but the object was already deallocated

It seems to happen in the cancel method (RemoteImage.swift, line 97), specifically on line 107 loadingState = .initial

Sample code The following code crashes almost immediately

struct TestView: View {
    func url() -> URL {
        let size = Int.random(in: 100...200)
        return URL(string: "https://picsum.photos/\(size)/\(size)")!
    }

    var body: some View {
        NavigationView {
            ScrollView([.horizontal]) {
                LazyHStack {
                    ForEach(1..<100, id:\.self) { i in
                        NavigationLink(destination: Text("")) {
                            URLImage(url: self.url()) {
                                image in
                                image
                                    .resizable()
                                    .clipShape(Circle())
                                    .frame(width: 300, height: 300)
                                    .clipped()
                            }
                        }.buttonStyle(PlainButtonStyle())
                    }
                }
            }
        }
    }
}

When I tweak the ForEach to get less values (20 worked for me) it doesn't immediately crash but only after I scroll through the items a little

Test data I used this site which let's you specify sizes to retrieve random images of that size 'https://picsum.photos/{width}/{height})'

Additional information: I've tried to narrow down the reason for the crash by making test views and changing them. I only got an error when the URLImage was inside a NavigationLink, that was itself inside a LazyStack.

dmytro-anokhin commented 3 years ago

Hey, thank you for proper bug report.

The crash is reproducible and I'm looking into it. This happens when object wrapped in @ObservedObject changes in onDisappear. I use it to cancel pending downloads. But the crash happens when onDisappear is triggered from dealloc of hosting UIView. I'm not sure if there is a guide not to publish changes in onDisappear.

For now, please comment out the line you mention (RemoteImage.swift - 107, loadingState = .initial). This will prevent publishing changes. I'm gonna do a bit more testing to see if there are any side effects, but this will probably be a workaround for the crash. You can point to version_2_1_2 branch.

NoahKamara commented 3 years ago

Hey, thanks for the quick reply. Keep up the great work I use this Package all the time :D

dmytro-anokhin commented 3 years ago

Hey, thanks, glad to hear this. The fix is in 2.1.2. I tested and it works. I'm closing this issue, feel free to reopen if you still can reproduce it. Cheers.