Skip to content

Commit 7b7a97f

Browse files
authored
Remove some escaping closures (#1493)
* Remove some escaping closures. * wip * wip * Add some canary tests to track down failures. * Remove a few more escaping closures.
1 parent e11ca0e commit 7b7a97f

File tree

6 files changed

+85
-69
lines changed

6 files changed

+85
-69
lines changed

Sources/ComposableArchitecture/Internal/Deprecations.swift

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1149,16 +1149,14 @@ extension ForEachStore {
11491149
{
11501150
let data = store.state.value
11511151
self.data = data
1152-
self.content = {
1153-
WithViewStore(store.scope(state: { $0.map { $0[keyPath: id] } })) { viewStore in
1154-
ForEach(Array(viewStore.state.enumerated()), id: \.element) { index, _ in
1155-
content(
1156-
store.scope(
1157-
state: { index < $0.endIndex ? $0[index] : data[index] },
1158-
action: { (index, $0) }
1159-
)
1152+
self.content = WithViewStore(store.scope(state: { $0.map { $0[keyPath: id] } })) { viewStore in
1153+
ForEach(Array(viewStore.state.enumerated()), id: \.element) { index, _ in
1154+
content(
1155+
store.scope(
1156+
state: { index < $0.endIndex ? $0[index] : data[index] },
1157+
action: { (index, $0) }
11601158
)
1161-
}
1159+
)
11621160
}
11631161
}
11641162
}

Sources/ComposableArchitecture/SwiftUI/ForEachStore.swift

Lines changed: 21 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ public struct ForEachStore<
8181
EachState, EachAction, Data: Collection, ID: Hashable, Content: View
8282
>: DynamicViewContent {
8383
public let data: Data
84-
let content: () -> Content
84+
let content: Content
8585

8686
/// Initializes a structure that computes views on demand from a store on a collection of data and
8787
/// an identified action.
@@ -100,34 +100,32 @@ public struct ForEachStore<
100100
>
101101
{
102102
self.data = store.state.value
103-
self.content = {
104-
WithViewStore(
105-
store,
106-
observe: { $0.ids },
107-
removeDuplicates: areOrderedSetsDuplicates
108-
) { viewStore in
109-
ForEach(viewStore.state, id: \.self) { id -> EachContent in
110-
// NB: We cache elements here to avoid a potential crash where SwiftUI may re-evaluate
111-
// views for elements no longer in the collection.
112-
//
113-
// Feedback filed: https://gist.github.com/stephencelis/cdf85ae8dab437adc998fb0204ed9a6b
114-
var element = store.state.value[id: id]!
115-
return content(
116-
store.scope(
117-
state: {
118-
element = $0[id: id] ?? element
119-
return element
120-
},
121-
action: { (id, $0) }
122-
)
103+
self.content = WithViewStore(
104+
store,
105+
observe: { $0.ids },
106+
removeDuplicates: areOrderedSetsDuplicates
107+
) { viewStore in
108+
ForEach(viewStore.state, id: \.self) { id -> EachContent in
109+
// NB: We cache elements here to avoid a potential crash where SwiftUI may re-evaluate
110+
// views for elements no longer in the collection.
111+
//
112+
// Feedback filed: https://gist.github.com/stephencelis/cdf85ae8dab437adc998fb0204ed9a6b
113+
var element = store.state.value[id: id]!
114+
return content(
115+
store.scope(
116+
state: {
117+
element = $0[id: id] ?? element
118+
return element
119+
},
120+
action: { (id, $0) }
123121
)
124-
}
122+
)
125123
}
126124
}
127125
}
128126

129127
public var body: some View {
130-
self.content()
128+
self.content
131129
}
132130
}
133131

Sources/ComposableArchitecture/SwiftUI/IfLetStore.swift

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,10 @@ public struct IfLetStore<State, Action, Content: View>: View {
4949
public init<IfContent, ElseContent>(
5050
_ store: Store<State?, Action>,
5151
@ViewBuilder then ifContent: @escaping (Store<State, Action>) -> IfContent,
52-
@ViewBuilder else elseContent: @escaping () -> ElseContent
52+
@ViewBuilder else elseContent: () -> ElseContent
5353
) where Content == _ConditionalContent<IfContent, ElseContent> {
5454
self.store = store
55+
let elseContent = elseContent()
5556
self.content = { viewStore in
5657
if var state = viewStore.state {
5758
return ViewBuilder.buildEither(
@@ -63,7 +64,7 @@ public struct IfLetStore<State, Action, Content: View>: View {
6364
)
6465
)
6566
} else {
66-
return ViewBuilder.buildEither(second: elseContent())
67+
return ViewBuilder.buildEither(second: elseContent)
6768
}
6869
}
6970
}

Sources/ComposableArchitecture/SwiftUI/SwitchStore.swift

Lines changed: 34 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -55,18 +55,18 @@ import SwiftUI
5555
/// case of an enum in reducers that operate on the entire enum.
5656
public struct SwitchStore<State, Action, Content: View>: View {
5757
public let store: Store<State, Action>
58-
public let content: () -> Content
58+
public let content: Content
5959

6060
init(
6161
store: Store<State, Action>,
62-
@ViewBuilder content: @escaping () -> Content
62+
@ViewBuilder content: () -> Content
6363
) {
6464
self.store = store
65-
self.content = content
65+
self.content = content()
6666
}
6767

6868
public var body: some View {
69-
self.content()
69+
self.content
7070
.environmentObject(StoreObservableObject(store: self.store))
7171
}
7272
}
@@ -135,26 +135,26 @@ extension CaseLet where EnumAction == CaseAction {
135135
/// a ``CaseLet`` for each case of the enum), then you must insert a ``Default`` view at the end of
136136
/// the ``SwitchStore``'s body.
137137
public struct Default<Content: View>: View {
138-
private let content: () -> Content
138+
private let content: Content
139139

140140
/// Initializes a ``Default`` view that computes content depending on if a store of enum state
141141
/// does not match a particular case.
142142
///
143143
/// - Parameter content: A function that returns a view that is visible only when the switch
144144
/// store's state does not match a preceding ``CaseLet`` view.
145-
public init(@ViewBuilder content: @escaping () -> Content) {
146-
self.content = content
145+
public init(@ViewBuilder content: () -> Content) {
146+
self.content = content()
147147
}
148148

149149
public var body: some View {
150-
self.content()
150+
self.content
151151
}
152152
}
153153

154154
extension SwitchStore {
155155
public init<State1, Action1, Content1, DefaultContent>(
156156
_ store: Store<State, Action>,
157-
@ViewBuilder content: @escaping () -> TupleView<
157+
@ViewBuilder content: () -> TupleView<
158158
(
159159
CaseLet<State, Action, State1, Action1, Content1>,
160160
Default<DefaultContent>
@@ -171,8 +171,8 @@ extension SwitchStore {
171171
>
172172
>
173173
{
174+
let content = content().value
174175
self.init(store: store) {
175-
let content = content().value
176176
return WithViewStore(store, removeDuplicates: { enumTag($0) == enumTag($1) }) { viewStore in
177177
if content.0.toCaseState(viewStore.state) != nil {
178178
content.0
@@ -208,7 +208,7 @@ extension SwitchStore {
208208

209209
public init<State1, Action1, Content1, State2, Action2, Content2, DefaultContent>(
210210
_ store: Store<State, Action>,
211-
@ViewBuilder content: @escaping () -> TupleView<
211+
@ViewBuilder content: () -> TupleView<
212212
(
213213
CaseLet<State, Action, State1, Action1, Content1>,
214214
CaseLet<State, Action, State2, Action2, Content2>,
@@ -229,8 +229,8 @@ extension SwitchStore {
229229
>
230230
>
231231
{
232+
let content = content().value
232233
self.init(store: store) {
233-
let content = content().value
234234
return WithViewStore(store, removeDuplicates: { enumTag($0) == enumTag($1) }) { viewStore in
235235
if content.0.toCaseState(viewStore.state) != nil {
236236
content.0
@@ -248,7 +248,7 @@ extension SwitchStore {
248248
file: StaticString = #file,
249249
fileID: StaticString = #fileID,
250250
line: UInt = #line,
251-
@ViewBuilder content: @escaping () -> TupleView<
251+
@ViewBuilder content: () -> TupleView<
252252
(
253253
CaseLet<State, Action, State1, Action1, Content1>,
254254
CaseLet<State, Action, State2, Action2, Content2>
@@ -283,7 +283,7 @@ extension SwitchStore {
283283
DefaultContent
284284
>(
285285
_ store: Store<State, Action>,
286-
@ViewBuilder content: @escaping () -> TupleView<
286+
@ViewBuilder content: () -> TupleView<
287287
(
288288
CaseLet<State, Action, State1, Action1, Content1>,
289289
CaseLet<State, Action, State2, Action2, Content2>,
@@ -308,8 +308,8 @@ extension SwitchStore {
308308
>
309309
>
310310
{
311+
let content = content().value
311312
self.init(store: store) {
312-
let content = content().value
313313
return WithViewStore(store, removeDuplicates: { enumTag($0) == enumTag($1) }) { viewStore in
314314
if content.0.toCaseState(viewStore.state) != nil {
315315
content.0
@@ -329,7 +329,7 @@ extension SwitchStore {
329329
file: StaticString = #file,
330330
fileID: StaticString = #fileID,
331331
line: UInt = #line,
332-
@ViewBuilder content: @escaping () -> TupleView<
332+
@ViewBuilder content: () -> TupleView<
333333
(
334334
CaseLet<State, Action, State1, Action1, Content1>,
335335
CaseLet<State, Action, State2, Action2, Content2>,
@@ -370,7 +370,7 @@ extension SwitchStore {
370370
DefaultContent
371371
>(
372372
_ store: Store<State, Action>,
373-
@ViewBuilder content: @escaping () -> TupleView<
373+
@ViewBuilder content: () -> TupleView<
374374
(
375375
CaseLet<State, Action, State1, Action1, Content1>,
376376
CaseLet<State, Action, State2, Action2, Content2>,
@@ -399,8 +399,8 @@ extension SwitchStore {
399399
>
400400
>
401401
{
402+
let content = content().value
402403
self.init(store: store) {
403-
let content = content().value
404404
return WithViewStore(store, removeDuplicates: { enumTag($0) == enumTag($1) }) { viewStore in
405405
if content.0.toCaseState(viewStore.state) != nil {
406406
content.0
@@ -427,7 +427,7 @@ extension SwitchStore {
427427
file: StaticString = #file,
428428
fileID: StaticString = #fileID,
429429
line: UInt = #line,
430-
@ViewBuilder content: @escaping () -> TupleView<
430+
@ViewBuilder content: () -> TupleView<
431431
(
432432
CaseLet<State, Action, State1, Action1, Content1>,
433433
CaseLet<State, Action, State2, Action2, Content2>,
@@ -474,7 +474,7 @@ extension SwitchStore {
474474
DefaultContent
475475
>(
476476
_ store: Store<State, Action>,
477-
@ViewBuilder content: @escaping () -> TupleView<
477+
@ViewBuilder content: () -> TupleView<
478478
(
479479
CaseLet<State, Action, State1, Action1, Content1>,
480480
CaseLet<State, Action, State2, Action2, Content2>,
@@ -507,8 +507,8 @@ extension SwitchStore {
507507
>
508508
>
509509
{
510+
let content = content().value
510511
self.init(store: store) {
511-
let content = content().value
512512
return WithViewStore(store, removeDuplicates: { enumTag($0) == enumTag($1) }) { viewStore in
513513
if content.0.toCaseState(viewStore.state) != nil {
514514
content.0
@@ -538,7 +538,7 @@ extension SwitchStore {
538538
file: StaticString = #file,
539539
fileID: StaticString = #fileID,
540540
line: UInt = #line,
541-
@ViewBuilder content: @escaping () -> TupleView<
541+
@ViewBuilder content: () -> TupleView<
542542
(
543543
CaseLet<State, Action, State1, Action1, Content1>,
544544
CaseLet<State, Action, State2, Action2, Content2>,
@@ -591,7 +591,7 @@ extension SwitchStore {
591591
DefaultContent
592592
>(
593593
_ store: Store<State, Action>,
594-
@ViewBuilder content: @escaping () -> TupleView<
594+
@ViewBuilder content: () -> TupleView<
595595
(
596596
CaseLet<State, Action, State1, Action1, Content1>,
597597
CaseLet<State, Action, State2, Action2, Content2>,
@@ -628,8 +628,8 @@ extension SwitchStore {
628628
>
629629
>
630630
{
631+
let content = content().value
631632
self.init(store: store) {
632-
let content = content().value
633633
return WithViewStore(store, removeDuplicates: { enumTag($0) == enumTag($1) }) { viewStore in
634634
if content.0.toCaseState(viewStore.state) != nil {
635635
content.0
@@ -662,7 +662,7 @@ extension SwitchStore {
662662
file: StaticString = #file,
663663
fileID: StaticString = #fileID,
664664
line: UInt = #line,
665-
@ViewBuilder content: @escaping () -> TupleView<
665+
@ViewBuilder content: () -> TupleView<
666666
(
667667
CaseLet<State, Action, State1, Action1, Content1>,
668668
CaseLet<State, Action, State2, Action2, Content2>,
@@ -721,7 +721,7 @@ extension SwitchStore {
721721
DefaultContent
722722
>(
723723
_ store: Store<State, Action>,
724-
@ViewBuilder content: @escaping () -> TupleView<
724+
@ViewBuilder content: () -> TupleView<
725725
(
726726
CaseLet<State, Action, State1, Action1, Content1>,
727727
CaseLet<State, Action, State2, Action2, Content2>,
@@ -762,8 +762,8 @@ extension SwitchStore {
762762
>
763763
>
764764
{
765+
let content = content().value
765766
self.init(store: store) {
766-
let content = content().value
767767
return WithViewStore(store, removeDuplicates: { enumTag($0) == enumTag($1) }) { viewStore in
768768
if content.0.toCaseState(viewStore.state) != nil {
769769
content.0
@@ -799,7 +799,7 @@ extension SwitchStore {
799799
file: StaticString = #file,
800800
fileID: StaticString = #fileID,
801801
line: UInt = #line,
802-
@ViewBuilder content: @escaping () -> TupleView<
802+
@ViewBuilder content: () -> TupleView<
803803
(
804804
CaseLet<State, Action, State1, Action1, Content1>,
805805
CaseLet<State, Action, State2, Action2, Content2>,
@@ -864,7 +864,7 @@ extension SwitchStore {
864864
DefaultContent
865865
>(
866866
_ store: Store<State, Action>,
867-
@ViewBuilder content: @escaping () -> TupleView<
867+
@ViewBuilder content: () -> TupleView<
868868
(
869869
CaseLet<State, Action, State1, Action1, Content1>,
870870
CaseLet<State, Action, State2, Action2, Content2>,
@@ -909,8 +909,8 @@ extension SwitchStore {
909909
>
910910
>
911911
{
912+
let content = content().value
912913
self.init(store: store) {
913-
let content = content().value
914914
return WithViewStore(store, removeDuplicates: { enumTag($0) == enumTag($1) }) { viewStore in
915915
if content.0.toCaseState(viewStore.state) != nil {
916916
content.0
@@ -949,7 +949,7 @@ extension SwitchStore {
949949
file: StaticString = #file,
950950
fileID: StaticString = #fileID,
951951
line: UInt = #line,
952-
@ViewBuilder content: @escaping () -> TupleView<
952+
@ViewBuilder content: () -> TupleView<
953953
(
954954
CaseLet<State, Action, State1, Action1, Content1>,
955955
CaseLet<State, Action, State2, Action2, Content2>,
@@ -1020,7 +1020,7 @@ extension SwitchStore {
10201020
DefaultContent
10211021
>(
10221022
_ store: Store<State, Action>,
1023-
@ViewBuilder content: @escaping () -> TupleView<
1023+
@ViewBuilder content: () -> TupleView<
10241024
(
10251025
CaseLet<State, Action, State1, Action1, Content1>,
10261026
CaseLet<State, Action, State2, Action2, Content2>,
@@ -1069,8 +1069,8 @@ extension SwitchStore {
10691069
>
10701070
>
10711071
{
1072+
let content = content().value
10721073
self.init(store: store) {
1073-
let content = content().value
10741074
return WithViewStore(store, removeDuplicates: { enumTag($0) == enumTag($1) }) { viewStore in
10751075
if content.0.toCaseState(viewStore.state) != nil {
10761076
content.0
@@ -1112,7 +1112,7 @@ extension SwitchStore {
11121112
file: StaticString = #file,
11131113
fileID: StaticString = #fileID,
11141114
line: UInt = #line,
1115-
@ViewBuilder content: @escaping () -> TupleView<
1115+
@ViewBuilder content: () -> TupleView<
11161116
(
11171117
CaseLet<State, Action, State1, Action1, Content1>,
11181118
CaseLet<State, Action, State2, Action2, Content2>,

0 commit comments

Comments
 (0)