SDWebImage / SDWebImageSwiftUI

SwiftUI Image loading and Animation framework powered by SDWebImage
https://sdwebimage.github.io/SDWebImageSwiftUI
MIT License
2.16k stars 223 forks source link

Fatal error: Attempted to read an unowned reference but the object was already deallocated #176

Open chrysb opened 3 years ago

chrysb commented 3 years ago

XCode Version 12.4 (12D4e) SDWebImageSwiftUI 2.0.1

We have a scenario where a view loads due to a cached auth state, and then after a server callback, if the user is unauth'd, it will remove that view from the hierarchy.

In that case, WebImage is also removed from the hierarchy, and it crashes. This is a blocking issue for us. We switched over from KFImage and that introduced this bug for us.

I can confirm that the crash stops happening when we comment out the WebImage from our view.

This is the codepath highlighted by XCode:

ImageManager.swift: 106

    /// Cancel the current url loading
    public func cancel() {
        if let operation = currentOperation {
            operation.cancel()
            currentOperation = nil
            isLoading = false
        }
    }

WebImage.swift: 113

                .onDisappear {
                    guard self.cancelOnDisappear else { return }
                    // When using prorgessive loading, the previous partial image will cause onDisappear. Filter this case
                    if self.imageManager.image == nil && !self.imageManager.isIncremental {
                        self.imageManager.cancel()
                    }
                }

And here's the callstack:

Thread 1 Queue : com.apple.main-thread (serial)
#0  0x00000001b098a414 in __pthread_kill ()
#1  0x00000001ce4e4b50 in pthread_kill ()
#2  0x000000018be63b74 in abort ()
#3  0x000000018699df20 in swift::fatalError(unsigned int, char const*, ...) ()
#4  0x000000018699e078 in swift::swift_abortRetainUnowned(void const*) ()
#5  0x00000001869ed844 in swift_unknownObjectUnownedLoadStrong ()
#6  0x0000000189935640 in static ViewGraph.viewRendererHost.getter ()
#7  0x00000001896b6e80 in closure #1 in PlatformViewChild.updateValue() ()
#8  0x00000001896b6054 in PlatformViewChild.updateValue() ()
#9  0x00000001893967fc in partial apply for implicit closure #2 in implicit closure #1 in closure #1 in closure #1 in Attribute.init<A>(_:) ()
#10 0x00000001abed3a50 in AG::Graph::UpdateStack::update() ()
#11 0x00000001abed3e84 in AG::Graph::update_attribute(AG::data::ptr<AG::Node>, bool) ()
#12 0x00000001abedd088 in AG::Subgraph::update(unsigned int) ()
#13 0x00000001899e9cdc in GraphHost.runTransaction() ()
#14 0x00000001899ece1c in GraphHost.runTransaction(_:) ()
#15 0x00000001899eb7a8 in GraphHost.flushTransactions() ()
#16 0x00000001899eac78 in specialized GraphHost.asyncTransaction<A>(_:mutation:style:) ()
#17 0x00000001895c52fc in AttributeInvalidatingSubscriber.invalidateAttribute() ()
#18 0x00000001895c51f8 in AttributeInvalidatingSubscriber.receive(_:) ()
#19 0x00000001895c5914 in protocol witness for Subscriber.receive(_:) in conformance AttributeInvalidatingSubscriber<A> ()
#20 0x0000000189773a34 in SubscriptionLifetime.Connection.receive(_:) ()
#21 0x0000000197071900 in ObservableObjectPublisher.Inner.send() ()
#22 0x00000001970710a8 in ObservableObjectPublisher.send() ()
#23 0x0000000197059fdc in PublishedSubject.send(_:) ()
#24 0x0000000197080994 in specialized static Published.subscript.setter ()
#25 0x000000019707ff74 in static Published.subscript.setter ()
#26 0x000000010c24e8e4 in ImageManager.isLoading.setter [inlined] ()
#27 0x000000010c24e8d0 in ImageManager.cancel() [inlined] at /Users/.../Pods/SDWebImageSwiftUI/SDWebImageSwiftUI/Classes/ImageManager.swift:111
#28 0x000000010c24e88c in closure #5 in closure #1 in WebImage.body.getter at /Users/.../Pods/SDWebImageSwiftUI/SDWebImageSwiftUI/Classes/WebImage.swift:117
#29 0x00000001894dab98 in thunk for @escaping @callee_guaranteed () -> () ()
#30 0x00000001894dabc0 in thunk for @escaping @callee_guaranteed () -> (@out ()) ()
#31 0x00000001894dab98 in thunk for @escaping @callee_guaranteed () -> () ()
#32 0x00000001894c9764 in static Update.end() ()
#33 0x00000001893cc088 in AppearanceEffect.disappeared() ()
#34 0x00000001893cc310 in static AppearanceEffect.willRemove(attribute:) ()
#35 0x00000001894e94e4 in closure #1 in AGSubgraphRef.willRemove() ()
#36 0x00000001abedd4fc in AG::Subgraph::apply(unsigned int, AG::ClosureFunctionAV<void, unsigned int>) ()
#37 0x00000001899eb630 in GraphHost.updateRemovedState() ()
#38 0x0000000189abe150 in _UIHostingView.updateRemovedState() ()
#39 0x0000000189ac02d0 in _UIHostingView.__deallocating_deinit ()
#40 0x0000000189ac03a8 in @objc _UIHostingView.__deallocating_deinit ()
#41 0x0000000197a707b0 in AutoreleasePoolPage::releaseUntil(objc_object**) ()
#42 0x0000000197a70650 in objc_autoreleasePoolPop ()
#43 0x00000001859081f0 in -[UIView dealloc] ()
#44 0x0000000197a4fb10 in object_cxxDestructFromClass(objc_object*, objc_class*) ()
#45 0x0000000197a66840 in objc_destructInstance ()
#46 0x0000000197a6d80c in _objc_rootDealloc ()
#47 0x000000018542165c in -[UIResponder dealloc] ()
#48 0x000000018590820c in -[UIView dealloc] ()
#49 0x0000000184b299a4 in -[UICollectionViewCell dealloc] ()
#50 0x0000000197a707b0 in AutoreleasePoolPage::releaseUntil(objc_object**) ()
#51 0x0000000197a70650 in objc_autoreleasePoolPop ()
#52 0x00000001859081f0 in -[UIView dealloc] ()
#53 0x00000001858a4420 in -[UIScrollView dealloc] ()
#54 0x000000018294f9f8 in __RELEASE_OBJECTS_IN_THE_ARRAY__ ()
#55 0x0000000182912740 in -[__NSArrayM dealloc] ()
#56 0x0000000197a707b0 in AutoreleasePoolPage::releaseUntil(objc_object**) ()
#57 0x0000000197a70650 in objc_autoreleasePoolPop ()
#58 0x0000000185d07704 in CA::Display::DisplayLink::dispatch_items(unsigned long long, unsigned long long, unsigned long long) ()
#59 0x0000000185de0a80 in display_timer_callback(__CFMachPort*, void*, long, void*) ()
#60 0x000000018298cdd0 in __CFMachPortPerform ()
#61 0x00000001829b1fe8 in __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ ()
#62 0x00000001829b1378 in __CFRunLoopDoSource1 ()
#63 0x00000001829ab08c in __CFRunLoopRun ()
#64 0x00000001829aa21c in CFRunLoopRunSpecific ()
#65 0x000000019a576784 in GSEventRunModal ()
#66 0x00000001853eaee8 in -[UIApplication _run] ()
#67 0x00000001853f075c in UIApplicationMain ()
#68 0x000000018997a210 in closure #1 in KitRendererCommon(_:) ()
#69 0x000000018997a19c in runApp<A>(_:) ()
#70 0x00000001894b2f90 in static App.main() ()
#71 0x00000001043f6738 in static TaptalkApp.$main() [inlined] ()
#72 0x00000001043f671c in main ()
#73 0x000000018266a6b0 in start ()
eren-celik commented 3 years ago

still same issue

dreampiggy commented 3 years ago

@erenlk Can you provide an demo to trigger this issue ? SwiftUI's code is easy for creating demo.

And, make sure you use the latest SDWebImageSwiftUI (current 2.1.0)

eren-celik commented 3 years ago

@dreampiggy

there is my code

            ScrollView{
                VStack {
                    TabView(selection: $selection){
                        ForEach(service.productSecondImageArray.indices , id: \.self) { index in
                            WebImage(url: URL(string: "https://aviled.com.tr/image/\(service.productSecondImageArray[index].image)"))
                                .resizable()
                                .indicator(.activity)
                                .frame(width: screen.width - 30, height: 400)
                                .aspectRatio(contentMode: .fit)
                                .cornerRadius(25)
                                .onTapGesture {
                                    self.zoomImageShow.toggle()
                                }
                                .sheet(isPresented: $zoomImageShow, content: {
                                    ZoomView(
                                        imageURL: "https://aviled.com.tr/image/\(service.productSecondImageArray[index].image)",
                                        thumbURL: "https://aviled.com.tr/image/\(service.productSecondImageArray[index].image)" ,
                                        productID: productID,
                                        array: $service.productSecondImageArray
                                    )
                                })
                                .shadow(color: colorScheme == .dark ? .secondarySystemBackground : Color(#colorLiteral(red: 0.8039215803, green: 0.8039215803, blue: 0.8039215803, alpha: 1)), radius: 5, x: 7, y: 7)
                                .padding()
                                .padding(.top,18)
                        }
                    }
                    .tabViewStyle(PageTabViewStyle(indexDisplayMode: .never))
                    .frame(width: screen.width, height: 420, alignment: .center)

                    HStack {
                        ForEach(service.productSecondImageArray.indices , id: \.self){ index in
                            Circle()
                                .frame(width: index == selection ? 10 : 5, height:  index == selection ? 15 : 10)
                                .foregroundColor(index == selection ? .primary : .secondary)
                                .animation(.spring())
                        }
                    }
                    .opacity(service.productSecondImageArray.count == 1 ? 0 : 1)
                }
}

I checked my version 2.0.2 but I get still same issue

eren-celik commented 3 years ago

and , get this error Thread 1: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)

eren-celik commented 3 years ago

Any Solutions ?

dreampiggy commented 3 years ago

Busying in daily work. Will try to debug in this weekend :)

chrysb commented 3 years ago

Thanks for working on this @dreampiggy !