Whereas testing on simulators, I’ve hit a difficulty the place ViewThatFits
seems to have a threading situation. This could trigger warnings or a crash.
The atmosphere is the next:
- Xcode 26.0 beta 5
- Swift 6 with strict concurrency checking
- minimal deployment goal iOS 17.0
- debug construct configuration
- iPhone 16 simulator working iOS 26.0 beta 5 (causes crash)
- iPhone 16 simulator working iOS 18.5 (causes crash)
- iPhone 15 simulator working iOS 17.5 (causes warnings)
The next code can be utilized to breed the issue when working with the next textual content dimension:
struct ContentView: View {
let item1 = "The fast brown fox jumps over the lazy canine."
let item2 = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."
@State personal var isExpanded = false
enum LayoutHint {
case regular
case spaceIsTight
case scrolling
}
personal func itemList(objects: [String], trace: LayoutHint) -> some View {
VStack(alignment: .main, spacing: 9) {
ForEach(Array(objects.enumerated()), id: .offset) { _, textual content in
Textual content(textual content)
.font(.footnote)
}
}
.body(maxWidth: .infinity, alignment: .main)
.fixedSize(horizontal: false, vertical: true)
}
personal func expandedExplanation(objects: [String]) -> some View {
ViewThatFits(in: .vertical) {
// If any of those 3 views are commented out, it really works
itemList(objects: objects, trace: .regular)
itemList(objects: objects, trace: .spaceIsTight)
ScrollView {
itemList(objects: objects, trace: .scrolling)
}
}
}
personal var chevronUp: some View {
Picture(systemName: "chevron.compact.up")
.imageScale(.medium)
.font(.title)
.fontWeight(.semibold)
.foregroundStyle(.grey)
// If vertical padding is added, it really works
// .padding(.vertical, 10)
.body(maxWidth: .infinity)
}
personal var expandedContent: some View {
VStack(alignment: .main, spacing: 20) {
expandedExplanation(objects: [item1, item2])
// If chevronUp is commented out, it really works
chevronUp
}
.padding()
}
personal var collapsedContent: some View {
Textual content("Present expanded")
.foregroundStyle(Colour(.hyperlink))
.padding()
.body(maxWidth: .infinity)
}
var physique: some View {
ZStack(alignment: .high) {
if isExpanded {
expandedContent
} else {
collapsedContent
}
}
.clipped()
.contentShape(.rect)
.background {
UnevenRoundedRectangle(
topLeadingRadius: 0,
bottomLeadingRadius: 20,
bottomTrailingRadius: 20,
topTrailingRadius: 0
)
.fill(Colour(.systemGray6))
.ignoresSafeArea(edges: .high)
}
.onTapGesture {
withAnimation(.easeInOut(period: 0.25)) {
isExpanded.toggle()
}
}
.body(maxHeight: .infinity, alignment: .high)
}
}
Right here is the way it ought to look when the highest part is expanded (word the textual content dimension):
The crash that occurs when working on the iPhone 16 simulator with iOS 26.0 beta 5 is as follows:
#0 0x0000000104986f18 in _dispatch_assert_queue_fail () #1 0x00000001049bc7f8 in dispatch_assert_queue$V2.chilly.1 () #2 0x0000000104986ea0 in dispatch_assert_queue () #3 0x0000000258e52678 in _swift_task_checkIsolatedSwift () #4 0x0000000258e93e0c in swift_task_isCurrentExecutorWithFlagsImpl () #5 0x0000000105750504 in closure #1 in closure #1 in ContentView.itemList(objects:trace:) () #6 0x00000001057507d4 in thunk for @escaping @callee_guaranteed (@unowned Int, @assured String) -> (@owned Textual content) () #7 0x00000001da012d50 in closure #1 () -> τ_0_2 in SwiftUI.ForEachState.merchandise(at: τ_0_0.Index, offset: Swift.Int) -> SwiftUI.ForEachState.Merchandise () #8 0x00000001da01d140 in partial apply forwarder for closure #1 () -> τ_0_2 in SwiftUI.ForEachState.merchandise(at: τ_0_0.Index, offset: Swift.Int) -> SwiftUI.ForEachState.Merchandise () #9 0x00000001d9d1cd28 in closure #1 (Swift.UnsafeMutablePointer>) throws -> τ_0_0 in SwiftUI.ObservationCenter._withObservation(do: () throws -> τ_0_0) throws -> (worth: τ_0_0, accessList: Swift.Optionally available) () #10 0x00000001d96c319c in partial apply forwarder for closure #1 (Swift.UnsafeMutablePointer>) throws -> τ_0_0 in SwiftUI.ObservationCenter._withObservation(do: () throws -> τ_0_0) throws -> (worth: τ_0_0, accessList: Swift.Optionally available) () #11 0x00000001d985e9f4 in withUnsafePointer () #12 0x00000001da012244 in merchandise () #13 0x00000001da00c850 in forEachItem () #14 0x00000001da01cea8 in perform signature specialization of SwiftUI.ForEachList.applyNodes(from: inout Swift.Int, model: SwiftUI._ViewList_IteratorStyle, checklist: Swift.Optionally available>, rework: SwiftUI._ViewList_TemporarySublistTransform, to: (inout Swift.Int, SwiftUI._ViewList_IteratorStyle, SwiftUI._ViewList_Node, SwiftUI._ViewList_TemporarySublistTransform) -> Swift.Bool) -> Swift.Bool () #15 0x00000001da0195a8 in protocol witness for SwiftUI.ViewList.applyNodes(from: inout Swift.Int, model: SwiftUI._ViewList_IteratorStyle, checklist: Swift.Optionally available>, rework: SwiftUI._ViewList_TemporarySublistTransform, to: (inout Swift.Int, SwiftUI._ViewList_IteratorStyle, SwiftUI._ViewList_Node, SwiftUI._ViewList_TemporarySublistTransform) -> Swift.Bool) -> Swift.Bool in conformance SwiftUI.ForEachList : SwiftUI.ViewList in SwiftUI () #16 0x00000001d9c08390 in applySublists () #17 0x00000001d9bfd9cc in applySublists () #18 0x00000001d9750750 in generic specialization of SwiftUI.DynamicContainerInfo.updateItems(disableTransitions: Swift.Bool) -> (modified: Swift.Bool, hasDepth: Swift.Bool) () #19 0x00000001d974f508 in generic specialization of SwiftUI.DynamicContainerInfo.updateValue() -> () () #20 0x00000001d9774448 in generic specialization > of implicit closure #1 (Swift.UnsafeMutableRawPointer, __C.AGAttribute) -> () in closure #1 () -> (Swift.UnsafeMutableRawPointer, __C.AGAttribute) -> () in closure #1 (Swift.UnsafePointer) -> AttributeGraph.Attribute in AttributeGraph.Attribute.init(τ_1_0) -> AttributeGraph.Attribute () #21 0x00000001c393b728 in AG::Graph::UpdateStack::replace () #22 0x00000001c393be18 in AG::Graph::update_attribute () #23 0x00000001c3943534 in AG::Graph::input_value_ref_slow () #24 0x00000001c395b19c in AGGraphGetValue () #25 0x00000001d9757894 in merged generic specialization of SwiftUI.DynamicLayoutComputer.updateValue() -> () () #26 0x00000001d9774728 in generic specialization > of implicit closure #1 (Swift.UnsafeMutableRawPointer, __C.AGAttribute) -> () in closure #1 () -> (Swift.UnsafeMutableRawPointer, __C.AGAttribute) -> () in closure #1 (Swift.UnsafePointer) -> AttributeGraph.Attribute in AttributeGraph.Attribute.init(τ_1_0) -> AttributeGraph.Attribute () #27 0x00000001c393b728 in AG::Graph::UpdateStack::replace () #28 0x00000001c393be18 in AG::Graph::update_attribute () #29 0x00000001c3943384 in AG::Graph::input_value_ref_slow () #30 0x00000001c395af58 in AGGraphGetInputValue () #31 0x00000001d99a0414 in dimension () #32 0x00000001d9d66cb4 in sizeThatFits () #33 0x00000001d9d67760 in protocol witness for SwiftUI.UnaryLayout.sizeThatFits(in: SwiftUI._ProposedSize, context: SwiftUI.SizeAndSpacingContext, youngster: SwiftUI.LayoutProxy) -> __C.CGSize in conformance SwiftUI._FlexFrameLayout : SwiftUI.UnaryLayout in SwiftUI () #34 0x00000001d9b70678 in merged SwiftUI.UnaryLayoutEngine.sizeThatFits(SwiftUI._ProposedSize) -> __C.CGSize () #35 0x00000001d9b7039c in ___lldb_unnamed_symbol196603 () #36 0x00000001d9ebe890 in sizeThatFits () #37 0x00000001d99a0480 in dimension () #38 0x00000001d97ec538 in sizeThatFits () #39 0x00000001d9b70678 in merged SwiftUI.UnaryLayoutEngine.sizeThatFits(SwiftUI._ProposedSize) -> __C.CGSize () #40 0x00000001d9b7039c in ___lldb_unnamed_symbol196603 () #41 0x00000001d9ebe890 in sizeThatFits () #42 0x00000001d9ebd23c in sizeThatFits () #43 0x00000001d8bab278 in closure #1 (SwiftUI._ViewOutputs, Swift.Bool) -> Swift.Bool in closure #1 () -> () in SwiftUI.SizeFittingLayoutComputer.Engine.explicitAlignment(_: SwiftUI.AlignmentKey, at: SwiftUI.ViewSize) -> Swift.Optionally available () #44 0x00000001d8ba9f7c in closure #1 (SwiftUI._ViewList_Sublist) -> Swift.Bool in SwiftUI.SizeFittingState.applyChildren(selectLast: Swift.Bool, to: (SwiftUI._ViewOutputs, Swift.Bool) -> Swift.Bool) -> () () #45 0x00000001d9c0763c in applySublists () #46 0x00000001d9c2aa88 in merged partial apply forwarder for closure #1 (inout Swift.Int, SwiftUI._ViewList_IteratorStyle, SwiftUI._ViewList_Node, SwiftUI._ViewList_TemporarySublistTransform) -> Swift.Bool in SwiftUI._ViewList_Node.applySublists(from: inout Swift.Int, model: SwiftUI._ViewList_IteratorStyle, rework: SwiftUI._ViewList_TemporarySublistTransform, to: (SwiftUI._ViewList_Sublist) -> Swift.Bool) -> Swift.Bool () #47 0x00000001d9c0be34 in applyNodes () #48 0x00000001d9c08390 in applySublists () #49 0x00000001d9bfd9cc in applySublists () #50 0x00000001d8ba88a4 in applyChildren () #51 0x00000001d8bab05c in closure #1 () -> () in SwiftUI.SizeFittingLayoutComputer.Engine.explicitAlignment(_: SwiftUI.AlignmentKey, at: SwiftUI.ViewSize) -> Swift.Optionally available () #52 0x00000001c393c164 in AG::Graph::with_update () #53 0x00000001d8bab4a4 in protocol witness for SwiftUI.LayoutEngine.explicitAlignment(_: SwiftUI.AlignmentKey, at: SwiftUI.ViewSize) -> Swift.Optionally available in conformance SwiftUI.SizeFittingLayoutComputer.Engine : SwiftUI.LayoutEngine in SwiftUI () #54 0x00000001d9ebe978 in explicitAlignment () #55 0x00000001d9f84570 in perform signature specialization Swift.Optionally available in SwiftUI.StackLayout.(UnmanagedImplementation in _00690F480F8D293143B214DBE6D72CD0).placeChildren(in: SwiftUI.ProposedViewSize) -> (), Argument Sorts : [Swift.Optional]> of SwiftUI.StackLayout.UnmanagedImplementation.sizeChildrenGenerallyWithConcreteMajorProposal(in: SwiftUI.ProposedViewSize, minorProposalForChild: (SwiftUI.StackLayout.Little one) -> Swift.Optionally available) -> () () #56 0x00000001d9f85980 in perform signature specialization Swift.Optionally available in SwiftUI.StackLayout.(UnmanagedImplementation in _00690F480F8D293143B214DBE6D72CD0).placeChildren(in: SwiftUI.ProposedViewSize) -> (), Argument Sorts : [Swift.Optional]> of SwiftUI.StackLayout.UnmanagedImplementation.placeChildren1(in: SwiftUI.ProposedViewSize, minorProposalForChild: (SwiftUI.StackLayout.Little one) -> Swift.Optionally available) -> () () #57 0x00000001d9f8382c in placeChildren () #58 0x00000001d9f83524 in explicitAlignment () #59 0x00000001d9f822fc in explicitAlignment () #60 0x00000001d997308c in merged protocol witness for SwiftUI.Format.explicitAlignment(of: SwiftUI.HorizontalAlignment, in: __C.CGRect, proposal: SwiftUI.ProposedViewSize, subviews: SwiftUI.LayoutSubviews, cache: inout τ_0_0.Cache) -> Swift.Optionally available in conformance SwiftUI._VStackLayout : SwiftUI.Format in SwiftUI () #61 0x00000001d9bab3e0 in closure #1 (Swift.UnsafeMutablePointer) -> Swift.Optionally available in closure #1 (Swift.UnsafeMutablePointer>) -> Swift.Optionally available in SwiftUI.ViewLayoutEngine.explicitAlignment(_: SwiftUI.AlignmentKey, at: SwiftUI.ViewSize) -> Swift.Optionally available () #62 0x00000001d9bab078 in closure #1 (Swift.UnsafeMutablePointer>) -> Swift.Optionally available in SwiftUI.ViewLayoutEngine.explicitAlignment(_: SwiftUI.AlignmentKey, at: SwiftUI.ViewSize) -> Swift.Optionally available () #63 0x00000001d9bb1218 in partial apply forwarder for closure #1 (Swift.UnsafeMutablePointer>) -> Swift.Optionally available in SwiftUI.ViewLayoutEngine.explicitAlignment(_: SwiftUI.AlignmentKey, at: SwiftUI.ViewSize) -> Swift.Optionally available () #64 0x00000001d985e9f4 in withUnsafePointer () #65 0x00000001d9baaf30 in explicitAlignment () #66 0x00000001d9bab978 in protocol witness for SwiftUI.LayoutEngine.explicitAlignment(_: SwiftUI.AlignmentKey, at: SwiftUI.ViewSize) -> Swift.Optionally available in conformance SwiftUI.ViewLayoutEngine : SwiftUI.LayoutEngine in SwiftUI () #67 0x00000001d9ebe978 in explicitAlignment () #68 0x00000001d99a11d0 in explicitAlignment () #69 0x00000001d9b70014 in explicitAlignment () #70 0x00000001d9b703b0 in protocol witness for SwiftUI.LayoutEngine.explicitAlignment(_: SwiftUI.AlignmentKey, at: SwiftUI.ViewSize) -> Swift.Optionally available in conformance SwiftUI.UnaryLayoutEngine : SwiftUI.LayoutEngine in SwiftUI () #71 0x00000001d9ebe978 in explicitAlignment () #72 0x00000001d97ea83c in SwiftUI.ViewDimensions.subscript.getter : (SwiftUI.AlignmentKey) -> CoreGraphics.CGFloat () #73 0x00000001d967f8cc in perform signature specialization __C.CGPoint in SwiftUI._ZStackLayout.placeSubviews(in: __C.CGRect, proposal: SwiftUI.ProposedViewSize, subviews: SwiftUI.LayoutSubviews, cache: inout ()) -> (), Argument Sorts : [SwiftUI._ZStackLayout]> of generic specialization , SwiftUI.ViewDimensions>, __C.CGPoint> of Swift.Sequence.cut back(τ_1_0, (τ_1_0, τ_0_0.Aspect) throws -> τ_1_0) throws -> τ_1_0 () #74 0x00000001d9683658 in perform signature specialization of SwiftUI._ZStackLayout.placeSubviews(in: __C.CGRect, proposal: SwiftUI.ProposedViewSize, subviews: SwiftUI.LayoutSubviews, cache: inout ()) -> () () #75 0x00000001d9baaae8 in closure #1 (Swift.UnsafeMutablePointer) -> () in SwiftUI.ViewLayoutEngine.childGeometries(at: SwiftUI.ViewSize, origin: __C.CGPoint) -> Swift.Array () #76 0x00000001d9baa898 in childGeometries () #77 0x00000001d9bab570 in static SwiftUI.ViewLayoutEngine.defaultAlignment(_: SwiftUI.AlignmentKey, dimension: SwiftUI.ViewSize, information: Swift.UnsafeMutableRawPointer) -> Swift.Optionally available () #78 0x00000001d9bab998 in protocol witness for static SwiftUI.DefaultAlignmentFunction.defaultAlignment(_: SwiftUI.AlignmentKey, dimension: SwiftUI.ViewSize, information: Swift.UnsafeMutableRawPointer) -> Swift.Optionally available in conformance SwiftUI.ViewLayoutEngine : SwiftUI.DefaultAlignmentFunction in SwiftUI () #79 0x00000001d9b8ae90 in merged protocol witness for SwiftUI.Format.explicitAlignment(of: SwiftUI.HorizontalAlignment, in: __C.CGRect, proposal: SwiftUI.ProposedViewSize, subviews: SwiftUI.LayoutSubviews, cache: inout τ_0_0.Cache) -> Swift.Optionally available in conformance SwiftUI._ZStackLayout : SwiftUI.Format in SwiftUI () #80 0x00000001d9bab3e0 in closure #1 (Swift.UnsafeMutablePointer) -> Swift.Optionally available in closure #1 (Swift.UnsafeMutablePointer>) -> Swift.Optionally available in SwiftUI.ViewLayoutEngine.explicitAlignment(_: SwiftUI.AlignmentKey, at: SwiftUI.ViewSize) -> Swift.Optionally available () #81 0x00000001d9bab078 in closure #1 (Swift.UnsafeMutablePointer>) -> Swift.Optionally available in SwiftUI.ViewLayoutEngine.explicitAlignment(_: SwiftUI.AlignmentKey, at: SwiftUI.ViewSize) -> Swift.Optionally available () #82 0x00000001d9bb1218 in partial apply forwarder for closure #1 (Swift.UnsafeMutablePointer>) -> Swift.Optionally available in SwiftUI.ViewLayoutEngine.explicitAlignment(_: SwiftUI.AlignmentKey, at: SwiftUI.ViewSize) -> Swift.Optionally available () #83 0x00000001d985e9f4 in withUnsafePointer () #84 0x00000001d9baaf30 in explicitAlignment () #85 0x00000001d9bab978 in protocol witness for SwiftUI.LayoutEngine.explicitAlignment(_: SwiftUI.AlignmentKey, at: SwiftUI.ViewSize) -> Swift.Optionally available in conformance SwiftUI.ViewLayoutEngine : SwiftUI.LayoutEngine in SwiftUI () #86 0x00000001d9ebe978 in explicitAlignment () #87 0x00000001d97ea83c in SwiftUI.ViewDimensions.subscript.getter : (SwiftUI.AlignmentKey) -> CoreGraphics.CGFloat () #88 0x00000001d9d65f7c in generic specialization of SwiftUI.FrameLayoutCommon.commonPlacement(of: SwiftUI.LayoutProxy, in: SwiftUI.PlacementContext, childProposal: SwiftUI._ProposedSize) -> SwiftUI._Placement () #89 0x00000001d9d671c4 in placement () #90 0x00000001d9d67718 in protocol witness for SwiftUI.UnaryLayout.placement(of: SwiftUI.LayoutProxy, in: τ_0_0.PlacementContextType) -> SwiftUI._Placement in conformance SwiftUI._FlexFrameLayout : SwiftUI.UnaryLayout in SwiftUI () #91 0x00000001d9b702c4 in childPlacement () #92 0x00000001d9ebe9c0 in childPlacement () #93 0x00000001d9bfd76c in merged generic specialization of SwiftUI.UnaryChildGeometry.worth.getter : SwiftUI.ViewGeometry () #94 0x00000001d9c1c860 in merged generic specialization > of implicit closure #1 (Swift.UnsafeMutableRawPointer, __C.AGAttribute) -> () in closure #1 () -> (Swift.UnsafeMutableRawPointer, __C.AGAttribute) -> () in closure #1 (Swift.UnsafePointer) -> AttributeGraph.Attribute in AttributeGraph.Attribute.init(τ_1_0) -> AttributeGraph.Attribute () #95 0x00000001c393b728 in AG::Graph::UpdateStack::replace () #96 0x00000001c394a874 in AG::Subgraph::replace () #97 0x00000001d9d009b4 in perform signature specialization () in SwiftUI.GraphHost.runTransaction() -> (), Argument Sorts : []> of SwiftUI.GraphHost.runTransaction(_: Swift.Optionally available, do: () -> (), id: Swift.Optionally available) -> () () #98 0x00000001da0f55a4 in closure #2 () -> () in SwiftUI.ViewGraph.updateOutputsAsync(at: SwiftUI.Time) -> Swift.Optionally available () #99 0x00000001c395a208 in AGGraphWithMainThreadHandler () #100 0x00000001da0efe80 in updateOutputsAsync () #101 0x00000001da0e87d4 in renderAsync () #102 0x00000001d982d87c in SwiftUI.ViewGraphHost.displayLinkTimer(timestamp: SwiftUI.Time, targetTimestamp: SwiftUI.Time, isAsyncThread: Swift.Bool) -> () () #103 0x00000001d982f5d8 in SwiftUI.ViewGraphDisplayLink.displayLinkTimer(__C.CADisplayLink) -> () () #104 0x00000001d982fb48 in @objc SwiftUI.ViewGraphDisplayLink.displayLinkTimer(__C.CADisplayLink) -> () () #105 0x000000018c450a24 in CA::Show::DisplayLinkItem::dispatch_ () #106 0x000000018c44c544 in CA::Show::DisplayLink::dispatch_items () #107 0x000000018c562284 in display_timer_callback () #108 0x00000001804114ac in __CFMachPortPerform () #109 0x000000018044dbe0 in __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ () #110 0x000000018044d1f8 in __CFRunLoopDoSource1 () #111 0x000000018044c2c0 in __CFRunLoopRun () #112 0x0000000180446e24 in _CFRunLoopRunSpecificWithOptions () #113 0x00000001810ca48c in -[NSRunLoop(NSRunLoop) runMode:beforeDate:] () #114 0x00000001810ca65c in -[NSRunLoop(NSRunLoop) run] () #115 0x00000001d9830bd4 in perform signature specialization of static SwiftUI.ViewGraphDisplayLink.asyncThread(arg: Swift.Optionally available) -> () () #116 0x00000001d982fba8 in @objc static SwiftUI.ViewGraphDisplayLink.asyncThread(arg: Swift.Optionally available) -> () () #117 0x00000001810f1358 in __NSThread__start__ () #118 0x0000000104a265f0 in _pthread_start ()
The warning that’s seen when working on the iPhone 15 simulator with iOS 17.5 is as follows:
warning: information race detected: @MainActor perform at StackOverflow/ContentView.swift:52 was not referred to as on the primary thread
Line 52 is the ForEach
contained in the perform itemList
.
It appears to me that this should be a SwiftUI bug, particularly since it’s only underneath sure circumstances. For instance, the difficulty just isn’t seen when any of the next adjustments are made:
- a special textual content dimension is used
- the second textual content merchandise is shorter (1 line as a substitute of three)
- any 1 of the three views inside
ViewthatFits
is commented out - vertical padding is added to the chevron
- the chevron is faraway from view.
These adjustments are usually not fixing the issue, they’re simply stopping it from occurring for the setup described. So I want a extra dependable repair. Particularly, I’m questioning if there could be a strategy to stop the issue with some sort of annotation or actor directive within the code?
How can the code be mounted in order that the problems are usually not seen when working as described?