Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WebImage Instantly crashes on load when inside a TabView #133

Closed
mjswen0923 opened this issue Sep 20, 2020 · 23 comments · Fixed by #178
Closed

WebImage Instantly crashes on load when inside a TabView #133

mjswen0923 opened this issue Sep 20, 2020 · 23 comments · Fixed by #178
Labels
bug Something isn't working help wanted Extra attention is needed

Comments

@mjswen0923
Copy link

mjswen0923 commented Sep 20, 2020

When used inside a TabView, any loading of a WebImage will immediately cause a crash. Here is the code that causes the crash:

TabView {

            Text("testing")
                .tabItem    {
                    Text("test")
                }
            WebImage(url: URL(string: "https://raw.githubusercontent.com/SDWebImage/SDWebImage/master/SDWebImage_logo.png"))
                .tabItem    {
                    Text("test2")
                }
}

I am using Xcode 12.0 with iOS 14.0, with SDWebImage 5.9.0 and SDWebImageSwiftUI 1.5.0.

Below is the stack trace:

#0 0x00000001b30dcc64 in AG::AttributeID::size() const ()
#1 0x00000001b30d0b2c in AG::Graph::add_indirect_attribute(AG::Subgraph&, AG::AttributeID, unsigned long, std::__1::optional, bool) ()
#2 0x00000001b30e2fe8 in (anonymous namespace)::create_indirect_attribute(unsigned int, std::__1::optional) ()
#3 0x00000001926b5bf4 in partial apply for thunk for @callee_guaranteed () -> (@unowned IndirectAttribute) ()
#4 0x00000001926b5a24 in closure #1 in AGSubgraphRef.apply(_:) ()
#5 0x00000001926b5818 in Attribute.makeReusable(indirectMap:) ()
#6 0x00000001926b1fd0 in closure #1 in closure #1 in closure #1 in ModifiedElements.makeElements(from:inputs:indirectMap:body:) ()
#7 0x00000001923fd324 in closure #1 in closure #1 in PlaceholderInfo.makeItem(placeholder:seed:) ()
#8 0x0000000192525784 in thunk for @callee_guaranteed (@in_guaranteed _ViewInputs, @guaranteed @escaping @callee_guaranteed (@in_guaranteed _ViewInputs) -> (@out _ViewOutputs)) -> (@out _ViewOutputs?) ()
#9 0x00000001926ad49c in closure #1 in closure #1 in _ViewList_Elements.makeOneElement(at:inputs:indirectMap:body:) ()
#10 0x00000001926b7d58 in partial apply for thunk for @callee_guaranteed (@in_guaranteed _ViewInputs, @guaranteed @escaping @callee_guaranteed (@in_guaranteed _ViewInputs) -> (@out _ViewOutputs)) -> (@out _ViewOutputs?, @unowned Bool) ()
#11 0x00000001926b1e78 in closure #1 in closure #1 in ModifiedElements.makeElements(from:inputs:indirectMap:body:) ()
#12 0x00000001926b7d94 in partial apply for closure #1 in closure #1 in ModifiedElements.makeElements(from:inputs:indirectMap:body:) ()
#13 0x00000001926b7d58 in partial apply for thunk for @callee_guaranteed (@in_guaranteed _ViewInputs, @guaranteed @escaping @callee_guaranteed (@in_guaranteed _ViewInputs) -> (@out _ViewOutputs)) -> (@out _ViewOutputs?, @unowned Bool) ()
#14 0x00000001926b1e78 in closure #1 in closure #1 in ModifiedElements.makeElements(from:inputs:indirectMap:body:) ()
#15 0x00000001926b7d94 in partial apply for closure #1 in closure #1 in ModifiedElements.makeElements(from:inputs:indirectMap:body:) ()
#16 0x00000001926b7d58 in partial apply for thunk for @callee_guaranteed (@in_guaranteed _ViewInputs, @guaranteed @escaping @callee_guaranteed (@in_guaranteed _ViewInputs) -> (@out _ViewOutputs)) -> (@out _ViewOutputs?, @unowned Bool) ()
#17 0x00000001926b1e78 in closure #1 in closure #1 in ModifiedElements.makeElements(from:inputs:indirectMap:body:) ()
#18 0x00000001926b7d94 in partial apply for closure #1 in closure #1 in ModifiedElements.makeElements(from:inputs:indirectMap:body:) ()
#19 0x00000001926afe78 in UnaryElements.makeElements(from:inputs:indirectMap:body:) ()
#20 0x00000001926b3350 in SubgraphElements.makeElements(from:inputs:indirectMap:body:) ()
#21 0x00000001926b1d5c in closure #1 in ModifiedElements.makeElements(from:inputs:indirectMap:body:) ()
#22 0x00000001926b1c28 in ModifiedElements.makeElements(from:inputs:indirectMap:body:) ()
#23 0x00000001926b1d5c in closure #1 in ModifiedElements.makeElements(from:inputs:indirectMap:body:) ()
#24 0x00000001926b1c28 in ModifiedElements.makeElements(from:inputs:indirectMap:body:) ()
#25 0x00000001926b1d5c in closure #1 in ModifiedElements.makeElements(from:inputs:indirectMap:body:) ()
#26 0x00000001926b1c28 in ModifiedElements.makeElements(from:inputs:indirectMap:body:) ()
#27 0x00000001926b3350 in SubgraphElements.makeElements(from:inputs:indirectMap:body:) ()
#28 0x00000001926ad420 in closure #1 in ViewList_Elements.makeOneElement(at:inputs:indirectMap:body:) ()
#29 0x00000001923fcedc in closure #1 in PlaceholderInfo.makeItem(placeholder:seed:) ()
#30 0x00000001923fc984 in PlaceholderInfo.updateValue() ()
#31 0x00000001920d83e4 in partial apply for specialized implicit closure #2 in implicit closure #1 in closure #1 in closure #1 in Attribute.init
(:) ()
#32 0x00000001b30cc194 in AG::Graph::UpdateStack::update() ()
#33 0x00000001b30cc5c8 in AG::Graph::update_attribute(AG::data::ptrAG::Node, bool) ()
#34 0x00000001b30d5728 in AG::Subgraph::update(unsigned int) ()
#35 0x0000000192738af4 in GraphHost.runTransaction() ()
#36 0x000000019224d780 in ViewGraph.updateOutputs(at:) ()
#37 0x000000019269604c in closure #1 in ViewRendererHost.render(interval:updateDisplayList:) ()
#38 0x0000000192695274 in ViewRendererHost.render(interval:updateDisplayList:) ()
#39 0x000000019214d748 in closure #1 in _UIHostingView.requestImmediateUpdate() ()
#40 0x0000000192801ec0 in thunk for @escaping @callee_guaranteed () -> () ()
#41 0x00000001050f3b68 in _dispatch_call_block_and_release ()
#42 0x00000001050f55f0 in _dispatch_client_callout ()
#43 0x0000000105104890 in dispatch_main_queue_callback_4CF ()
#44 0x000000018b9731e4 in CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE ()
#45 0x000000018b96d3b4 in __CFRunLoopRun ()
#46 0x000000018b96c4bc in CFRunLoopRunSpecific ()
#47 0x00000001a23f1820 in GSEventRunModal ()
#48 0x000000018e310734 in -[UIApplication run] ()
#49 0x000000018e315e10 in UIApplicationMain ()
#50 0x00000001926cd32c in closure #1 in KitRendererCommon(
:) ()
#51 0x00000001926cd2b8 in runApp(
:) ()
#52 0x0000000192246b08 in static App.main() ()
#53 0x0000000104c130b4 in static SDWebImageTestCrashApp.$main() ()
#54 0x0000000104c13154 in main ()
#55 0x000000018b633e60 in start ()

@yonaskolb
Copy link

yonaskolb commented Sep 21, 2020

I'm also getting a crash in iOS 14.0 within the SwiftUI AG Graph when a list item with a WebImage is scrolled onto screen

@mjswen0923
Copy link
Author

I'm also getting a crash in iOS 14.0 within the SwiftUI AG Graph when a list item with a WebImage is scrolled onto screen

Was it AGGraph::getValue()? I was experiencing that as well, but this bug was much easier to repro and track down.

@dreampiggy
Copy link
Collaborator

Need some dig into SwiftUI issue of this. I didn't realize that user will put this WebImage inside the TabView.

@dreampiggy
Copy link
Collaborator

dreampiggy commented Sep 22, 2020

You can wrap that into a empty VStack or HStack.

var body: some View {
    TabView {
        Text("testing")
            .tabItem    {
                Text("test")
            }
        VStack {
            WebImage(url: URL(string: "https://raw.githubusercontent.com/SDWebImage/SDWebImage/master/SDWebImage_logo.png"))
        }
        .tabItem    {
            Text("test2")
        }
    }
}

@yonaskolb
Copy link

yonaskolb commented Sep 22, 2020

Was it AGGraph::getValue()? I was experiencing that as well, but this bug was much easier to repro and track down.

Yep
Screen Shot 2020-09-22 at 3 32 53 pm

@yonaskolb
Copy link

I've created a simple repro project that shows the crash I'm experiencing in lists and buttons in iOS 14.0
SDWebImageCrash.zip

@djr
Copy link

djr commented Sep 23, 2020

I'm also experiencing the AGGraph::getValue() crash but not inside a TabView. The images are in a SwiftUI List view. Wrapping them in an empty VStack or HStack didn't help.

@mjswen0923
Copy link
Author

I'm also experiencing the AGGraph::getValue() crash but not inside a TabView. The images are in a SwiftUI List view. Wrapping them in an empty VStack or HStack didn't help.

Yes, I had that problem as well

@dreampiggy dreampiggy added bug Something isn't working help wanted Extra attention is needed labels Sep 25, 2020
@dreampiggy
Copy link
Collaborator

Need some SwiftUI expert to help. This sounds like Apple's SwiftUI internal changes which effect the current WebImage implementation.

@Baza207
Copy link

Baza207 commented Oct 14, 2020

I'm having a similar issue in a ListView. I have a feeling it's an Async issue, where something returns but the returned thing has already been released by SwiftUI in the background. Harder to catch in a ListView though, but I get exactly the same AGGraph error.

I'm not sure if this is a big in SwiftUI though or something that can be fixed with work arounds, etc.

@WunDaii
Copy link

WunDaii commented Oct 18, 2020

I'm also getting the same AGGraph::getValue() crash inside a List unfortunately.

@ramunasjurgilas
Copy link

I am getting this crash as well. HStack or VStack not helping.
image

@maurovc
Copy link

maurovc commented Nov 19, 2020

I'm also experiencing this issue. Did someone find a workaround or any info that could help? I'm happy to help even-though I'm not a SwiftUI expert.

Here's my crash stack trace:

Thread 0 name:
Thread 0 Crashed:
0   libsystem_kernel.dylib        	0x00000001b4413414 __pthread_kill + 8
1   libsystem_pthread.dylib       	0x00000001d092bb40 pthread_kill + 272 (pthread.c:1388)
2   libsystem_c.dylib             	0x0000000190838b74 abort + 104 (abort.c:110)
3   libswiftCore.dylib            	0x000000018b448f68 swift::fatalError(unsigned int, char const*, ...) + 60 (Errors.cpp:393)
4   libswiftCore.dylib            	0x000000018b4490c0 swift::swift_abortRetainUnowned(void const*) + 36 (Errors.cpp:460)
5   libswiftCore.dylib            	0x000000018b49888c swift_unknownObjectUnownedLoadStrong + 76 (SwiftObject.mm:895)
6   SwiftUI                       	0x000000018dee6ad0 ViewGraph.graphDelegate.getter + 16 (ViewGraph.swift:234)
7   SwiftUI                       	0x000000018e3f994c GraphHost.flushTransactions() + 204 (GraphHost.swift:441)
8   SwiftUI                       	0x000000018e3f8e10 specialized GraphHost.asyncTransaction<A>(_:mutation:style:) + 252 (<compiler-generated>:0)
9   SwiftUI                       	0x000000018dff0500 AttributeInvalidatingSubscriber.invalidateAttribute() + 236 (AttributeInvalidatingSubscriber.swift:89)
10  SwiftUI                       	0x000000018dff03fc AttributeInvalidatingSubscriber.receive(_:) + 100 (AttributeInvalidatingSubscriber.swift:53)
11  SwiftUI                       	0x000000018dff0b18 protocol witness for Subscriber.receive(_:) in conformance AttributeInvalidatingSubscriber<A> + 24 (<compiler-generated>:0)
12  SwiftUI                       	0x000000018e19379c SubscriptionLifetime.Connection.receive(_:) + 100 (SubscriptionLifetime.swift:195)
13  Combine                       	0x000000019b0b900c ObservableObjectPublisher.Inner.send() + 136 (ObservableObject.swift:115)
14  Combine                       	0x000000019b0b87b4 ObservableObjectPublisher.send() + 632 (ObservableObject.swift:153)
15  Combine                       	0x000000019b0a16e8 PublishedSubject.send(_:) + 136 (PublishedSubject.swift:82)
16  Combine                       	0x000000019b0c7ffc specialized static Published.subscript.setter + 388 (Published.swift:0)
17  Combine                       	0x000000019b0c75dc static Published.subscript.setter + 40 (<compiler-generated>:0)
18  Project Calathea              	0x0000000101090054 _hidden#1975_ + 364 (__hidden#2238_:0)
19  SwiftUI                       	0x000000018df08338 thunk for @escaping @callee_guaranteed () -> () + 28 (<compiler-generated>:0)
20  SwiftUI                       	0x000000018df08360 thunk for @escaping @callee_guaranteed () -> (@out ()) + 28 (<compiler-generated>:0)
21  SwiftUI                       	0x000000018df08338 thunk for @escaping @callee_guaranteed () -> () + 28 (<compiler-generated>:0)
22  SwiftUI                       	0x000000018def70f0 static Update.end() + 536 (<compiler-generated>:0)
23  SwiftUI                       	0x000000018ddff054 AppearanceEffect.disappeared() + 332 (Update.swift:45)
24  SwiftUI                       	0x000000018ddff2dc static AppearanceEffect.willRemove(attribute:) + 48 (AppearanceActionModifier.swift:105)
25  SwiftUI                       	0x000000018df16b3c closure #1 in AGSubgraphRef.willRemove() + 80 (AttributeGraphAdditions.swift:83)
26  AttributeGraph                	0x00000001afa4066c AG::Subgraph::apply(unsigned int, AG::ClosureFunctionAV<void, unsigned int>) + 420 (ag-closure.h:108)
27  SwiftUI                       	0x000000018e3f97f4 GraphHost.updateRemovedState() + 152 (<compiler-generated>:0)
28  SwiftUI                       	0x000000018e4c8010 _UIHostingView.updateRemovedState() + 112 (GraphHost.swift:107)
29  SwiftUI                       	0x000000018e4ca154 _UIHostingView.__deallocating_deinit + 52 (UIHostingView.swift:1437)
30  SwiftUI                       	0x000000018e4ca22c @objc _UIHostingView.__deallocating_deinit + 28 (<compiler-generated>:0)
31  libobjc.A.dylib               	0x000000019ba8a7b0 AutoreleasePoolPage::releaseUntil(objc_object**) + 204 (NSObject.mm:944)
32  libobjc.A.dylib               	0x000000019ba8a650 objc_autoreleasePoolPop + 212 (NSObject.mm:1211)
33  UIKitCore                     	0x000000018a3e0104 -[UIView dealloc] + 876 (UIView.m:4639)
34  libobjc.A.dylib               	0x000000019ba69b10 object_cxxDestructFromClass(objc_object*, objc_class*) + 112 (objc-class.mm:455)
35  libobjc.A.dylib               	0x000000019ba80840 objc_destructInstance + 80 (objc-class.mm:469)
36  libobjc.A.dylib               	0x000000019ba8780c _objc_rootDealloc + 80 (objc-runtime-new.mm:8131)
37  UIKitCore                     	0x0000000189ef8928 -[UIResponder dealloc] + 156 (UIResponder.m:136)
38  UIKitCore                     	0x000000018a3e0120 -[UIView dealloc] + 904 (UIView.m:4640)
39  UIKitCore                     	0x00000001896020b8 -[UICollectionViewCell dealloc] + 108 (UICollectionViewCell.m:910)
40  libobjc.A.dylib               	0x000000019ba8a7b0 AutoreleasePoolPage::releaseUntil(objc_object**) + 204 (NSObject.mm:944)
41  libobjc.A.dylib               	0x000000019ba8a650 objc_autoreleasePoolPop + 212 (NSObject.mm:1211)
42  QuartzCore                    	0x000000018a87ff60 CA::Context::commit_transaction(CA::Transaction*, double, double*) + 544 (CAInternal.h:330)
43  QuartzCore                    	0x000000018a8ab36c CA::Transaction::commit() + 732 (CATransactionInternal.mm:449)
44  QuartzCore                    	0x000000018a8ac6fc CA::Transaction::observer_callback(__CFRunLoopObserver*, unsigned long, void*) + 96 (CATransactionInternal.mm:925)
45  CoreFoundation                	0x000000018748f358 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 36 (CFRunLoop.c:1799)
46  CoreFoundation                	0x00000001874895c4 __CFRunLoopDoObservers + 576 (CFRunLoop.c:1912)
47  CoreFoundation                	0x0000000187489b74 __CFRunLoopRun + 1056 (CFRunLoop.c:2953)
48  CoreFoundation                	0x000000018748921c CFRunLoopRunSpecific + 600 (CFRunLoop.c:3242)
49  GraphicsServices              	0x000000019e508784 GSEventRunModal + 164 (GSEvent.c:2259)
50  UIKitCore                     	0x0000000189ec2200 -[UIApplication _run] + 1072 (UIApplication.m:3266)
51  UIKitCore                     	0x0000000189ec7a74 UIApplicationMain + 168 (UIApplication.m:4738)
52  Project Calathea              	0x0000000100fe7770 main + 68 (Auth.swift:7)
53  libdyld.dylib                 	0x00000001871496c0 start + 4

Thanks!

@Insofan
Copy link
Member

Insofan commented Nov 20, 2020

@yonaskolb I have run your demo on Xcode12.2 (12B45b) simulator and I can't reproduce crash. But poster‘s code reproduce crash.

@yonaskolb
Copy link

The crash in List and Button (my sample project above) seems to be fixed in iOS 14.2

@yonaskolb
Copy link

yonaskolb commented Dec 6, 2020

As for your crash @mjswen0923 (which is indeed not fixed in iOS 14.2) a workaround seems to be to wrap the WebImage in a HStack

TabView {
    Text("testing")
        .tabItem    {
            Text("test")
        }
    HStack {
        WebImage(url: URL(string: "https://raw.githubusercontent.com/SDWebImage/SDWebImage/master/SDWebImage_logo.png"))
    }
        .tabItem    {
            Text("test2")
        }
}

EDIT: I see now @dreampiggy already provided that solution above 😄

@dreampiggy
Copy link
Collaborator

dreampiggy commented Dec 7, 2020

Any extra workaround without that HStack to use on WebImage ?

Or can you have a try with other open source SwiftUI component to see whether they can used in TabView natively ? So that I can learn from them:

KFImage: https://github.com/onevcat/Kingfisher/releases/tag/5.15.8
URLImage: https://github.com/dmytro-anokhin/url-image

@yonaskolb
Copy link

Saw an interesting reference to SwiftUI crashes in the Kingfisher release notes https://github.com/onevcat/Kingfisher/releases/tag/6.2.0

Not sure if the fix they implemented there helps things here, I haven't delved into how SDWebImage handles this, but might be interesting to look at onevcat/Kingfisher#1642

@dreampiggy
Copy link
Collaborator

dreampiggy commented Mar 9, 2021

@yonaskolb We already don't use @State. Can't version 2.0 solve this issue ?

Seems this issue is already stale.

@yonaskolb
Copy link

Oh, didn't see there was a release, will test and get back to you!

@dreampiggy
Copy link
Collaborator

dreampiggy commented Mar 9, 2021

Actually. TabView has some limitation for tabbar item:

Tab views only support tab items of type Text, Image, or an image followed by text. Passing any other type of view results in a visible but empty tab item.

You can use Image with ImageManager instead to supports dynamic URL bar item. Which may be better and follows Apples framework design.

@yonaskolb
Copy link

Looks like the same crash with List and Button is still present before iOS 14.2 with SDWebImageSwiftUI 2.0.1

@dreampiggy
Copy link
Collaborator

Should be fixed in v2.0.2

However, I strongly recommended don't use WebImage as the top level View component. Wrap it inside List, HStack is a better idea.

Since the layout of Web URL can not have the intrinsicContentSize (Which may changed when loading image from network). So you'd better provide the frame modifier to limit it container size.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working help wanted Extra attention is needed
Projects
None yet
9 participants