Open navyseai opened 3 years ago
I don't think you need to call devicesSection.reload()
at the beginning if you are to remove all rows later. Does it change anything if you remove that?
I don't think you need to call
devicesSection.reload()
at the beginning if you are to remove all rows later. Does it change anything if you remove that?
yea that was probably an attempt to force the app to enter a consistent state before the intended changes
i've stumble on this
do you think that wrapping my
populateDevicesSection() and self.vc.tableView.reloadData()
in beginUpdates and endUpdates would help?
It might help. Have you tried it?
It might help. Have you tried it?
We are currently testing it but like I said I haven't been able to reproduce it. If it passes in QA we will archive the bug and see if re-appears.
Seeing the same issue here. Only appearing in production, can't reproduce in QA.
Eureka version: 5.3.4 XCode verison: 13.0 Swift version: 5.0
Fatal Exception: NSRangeException
0 CoreFoundation 0x129708 __exceptionPreprocess
1 libobjc.A.dylib 0x287a8 objc_exception_throw
2 CoreFoundation 0x19b9c8 -[__NSCFString characterAtIndex:].cold.1
3 CoreFoundation 0x3870 -[__NSArrayM objectAtIndex:]
4 Eureka 0x19c00 FormViewController.tableView(_:heightForRowAt:)
5 Eureka 0x19dec @objc FormViewController.tableView(_:heightForRowAt:)
6 UIKitCore 0xe0018c -[UITableView _classicHeightForRowAtIndexPath:]
7 UIKitCore 0xe04a6c -[UITableView _heightForRowAtIndexPath:]
8 UIKitCore 0xe17d90 -[UISectionRowData heightForRow:inSection:canGuess:]
9 UIKitCore 0xe1cdfc -[UITableViewRowData heightForRow:inSection:canGuess:adjustForReorderedRow:]
10 UIKitCore 0xe1e4b0 -[UITableViewRowData rectForRow:inSection:heightCanBeGuessed:]
11 UIKitCore 0xe1e644 -[UITableViewRowData rectForGlobalRow:heightCanBeGuessed:]
12 UIKitCore 0xdc4d6c -[UITableView _updateVisibleCellsNow:]
13 UIKitCore 0xdbf268 -[UITableView _setupCellAnimations]
14 UIKitCore 0xdd9c40 -[UITableView beginUpdates]
15 Eureka 0x18da4 FormViewController.sectionsHaveBeenRemoved(_:at:) + 709 (Core.swift:709)
16 Eureka 0x5a930 specialized Form.KVOWrapper.observeValue(forKeyPath:of:change:context:) + 333 (Form.swift:333)
17 Eureka 0x50940 @objc Form.KVOWrapper.observeValue(forKeyPath:of:change:context:) (<compiler-generated>)
18 Foundation 0x10be1c NSKeyValueNotifyObserver
19 Foundation 0x10e394 NSKeyValueDidChange
20 Foundation 0x10de00 -[NSObject(NSKeyValueObservingPrivate) _changeValueForKeys:count:maybeOldValuesDict:maybeNewValuesDict:usingBlock:]
21 Foundation 0x470e0 -[NSObject(NSKeyValueObservingPrivate) _changeValueForKey:key:key:usingBlock:]
22 Foundation 0x107ebc _NSSetObjectValueAndNotify
23 Eureka 0x59158 specialized Form.removeAll(keepingCapacity:) + 320 (Form.swift:320)
24 Air Trail 0x29bc70 SettingsFormViewController.setupFormViews() + 44 (SettingsViewController.swift:44)
25 Air Trail 0x29cb30 SettingsFormViewController.viewWillAppear(_:) + 89 (SettingsViewController.swift:89)
26 Air Trail 0x29cd10 @objc SettingsFormViewController.viewWillAppear(_:) (<compiler-generated>)
27 UIKitCore 0x4a780c -[UIViewController _setViewAppearState:isAnimating:]
28 UIKitCore 0x4a7e1c __52-[UIViewController _setViewAppearState:isAnimating:]_block_invoke
29 CoreFoundation 0xa7564 __NSARRAY_IS_CALLING_OUT_TO_A_BLOCK__
30 CoreFoundation 0x1b4c -[__NSSingleObjectArrayI enumerateObjectsWithOptions:usingBlock:]
31 UIKitCore 0x4a7ab8 -[UIViewController _setViewAppearState:isAnimating:]
32 UIKitCore 0x4a7fcc -[UIViewController __viewWillAppear:]
33 UIKitCore 0x3b3494 -[UITabBarController transitionFromViewController:toViewController:transition:shouldSetSelected:]
34 UIKitCore 0x3aea70 -[UITabBarController _setSelectedViewController:]
35 UIKitCore 0x3ae874 -[UITabBarController setSelectedViewController:]
36 UIKitCore 0x3b2648 -[UITabBarController _tabBarItemClicked:]
37 UIKitCore 0xbd163c -[UIApplication sendAction:to:from:forEvent:]
38 UIKitCore 0x1e640c -[UITabBar _sendAction:withEvent:]
39 UIKitCore 0xbd163c -[UIApplication sendAction:to:from:forEvent:]
40 UIKitCore 0x5036ac -[UIControl sendAction:to:forEvent:]
41 UIKitCore 0x5039fc -[UIControl _sendActionsForEvents:withEvent:]
42 UIKitCore 0x1e9374 -[UITabBar _buttonUp:]
43 UIKitCore 0xbd163c -[UIApplication sendAction:to:from:forEvent:]
44 UIKitCore 0x5036ac -[UIControl sendAction:to:forEvent:]
45 UIKitCore 0x5039fc -[UIControl _sendActionsForEvents:withEvent:]
46 UIKitCore 0x502278 -[UIControl touchesEnded:withEvent:]
47 UIKitCore 0x7042f8 _UIGestureEnvironmentUpdate
48 CoreFoundation 0xa2588 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__
49 CoreFoundation 0x9c6ac __CFRunLoopDoObservers
50 CoreFoundation 0x9cc58 __CFRunLoopRun
51 CoreFoundation 0x9c308 CFRunLoopRunSpecific
52 GraphicsServices 0x3734 GSEventRunModal
53 UIKitCore 0xbca75c -[UIApplication _run]
54 UIKitCore 0xbcffcc UIApplicationMain
REDACTED
56 libdyld.dylib 0x1cf8 start
And the relevant code:
func setupFormViews() {
UIView.setAnimationsEnabled(false)
form.removeAll()
form
+++ Section() { section in section.header = ReusableSectionHeaderView.compose(with: "Title") }
<<< {A ROW}
if DedicatedAircraftDeviceManager.paired {
form
+++ Section() { section in section.header = ReusableSectionHeaderView.compose(with: "Section Title") }
<<< {A ROW}
<<< {A ROW}
<<< {A ROW}
<<< {A ROW}
<<< {A ROW}
<<< {A ROW}
<<< {A ROW}
<<< {A ROW}
<<< {A ROW}
<<< {A ROW}
<<< {A ROW}
}
if {CONDITIONAL} {
form
+++ Section() { section in section.header = ReusableSectionHeaderView.compose(with: "Title ") }
<<< SettingsRowComposer.userLogoutRow(delegate: self)
} else {
form
+++ Section() { section in section.header = ReusableSectionHeaderView.compose(with: "Title") }
<<< {A ROW}
+++ Section() { section in section.header = ReusableSectionHeaderView.compose(with: "Title") }
<<< {A ROW}
}
form
+++ Section() { section in section.header = ReusableSectionHeaderView.compose(with: "Title") }
<<< {A ROW}
UIView.setAnimationsEnabled(true)
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
setupFormViews()
}
We are also seeing another crash that may be relevant here.
Here's the stacktrace:
Crashed: com.apple.main-thread
0 UIKitCore 0xe1d3e4 -[UITableViewRowData sectionLocationForRow:inSection:] + 40
1 UIKitCore 0xe24d24 -[_UITableViewUpdateSupport(Private) _setupAnimationsForExistingVisibleCells] + 784
2 UIKitCore 0xe2bc7c -[_UITableViewUpdateSupport _setupAnimations] + 112
3 UIKitCore 0xdc9890 -[UITableView _updateWithItems:updateSupport:] + 2424
4 UIKitCore 0xdc1e54 -[UITableView _endCellAnimationsWithContext:] + 11172
5 UIKitCore 0xdd9d80 -[UITableView endUpdatesWithContext:] + 128
6 Eureka 0x18ed8 FormViewController.sectionsHaveBeenRemoved(_:at:) + 712 (Core.swift:712)
7 Eureka 0x5a9a8 specialized Form.KVOWrapper.observeValue(forKeyPath:of:change:context:) + 333 (Form.swift:333)
8 Eureka 0x509b8 @objc Form.KVOWrapper.observeValue(forKeyPath:of:change:context:) + 4326148536 (<compiler-generated>:4326148536)
9 Foundation 0x10be1c NSKeyValueNotifyObserver + 292
10 Foundation 0x10e394 NSKeyValueDidChange + 328
11 Foundation 0x10de00 -[NSObject(NSKeyValueObservingPrivate) _changeValueForKeys:count:maybeOldValuesDict:maybeNewValuesDict:usingBlock:] + 644
12 Foundation 0x470e0 -[NSObject(NSKeyValueObservingPrivate) _changeValueForKey:key:key:usingBlock:] + 72
13 Foundation 0x107ebc _NSSetObjectValueAndNotify + 312
14 Eureka 0x591d0 specialized Form.removeAll(keepingCapacity:) + 320 (Form.swift:320)
15 Air Trail 0xbaa8c closure #1 in IndividualAircraftLogViewController.displayAppropriateSegment(defaultSegment:) + 347 (IndividualAircraftLogViewController+General.swift:347)
16 Air Trail 0x870614 thunk for @escaping @callee_guaranteed () -> () + 4316251668 (<compiler-generated>:4316251668)
17 libdispatch.dylib 0x13484 _dispatch_block_async_invoke2 + 148
18 libdispatch.dylib 0x481c _dispatch_client_callout + 20
19 libdispatch.dylib 0x12c70 _dispatch_main_queue_callback_4CF + 884
20 CoreFoundation 0xa3340 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 16
21 CoreFoundation 0x9d218 __CFRunLoopRun + 2524
22 CoreFoundation 0x9c308 CFRunLoopRunSpecific + 600
23 GraphicsServices 0x3734 GSEventRunModal + 164
24 UIKitCore 0xbca75c -[UIApplication _run] + 1072
25 UIKitCore 0xbcffcc UIApplicationMain + 168
REDACTED
27 libdyld.dylib 0x1cf8 start + 4
@chickendiver is the purpose of your code to completely reset the form? You could try just creating a form on a separate variable and end with self.form = newForm
.
For example:
let newForm = Form()
newForm +++ ...
<<< ...
self.form = newForm
This should avoid lots of removing and adding to the form
This is awesome, thank you! We've implemented this solution, and it appears to be working great in our QA environment. Will monitor in prod.
Wrapping removeAll calls in beginUpdates/endUpdates fixed it for me:
[formViewController.]tableView.beginUpdates()
[formViewController.]form.removeAll()
[formViewController.]tableView.endUpdates()
You can read why it happens here: https://openradar.appspot.com/36072360
There Apple replied recommending to place data source mutation and table view modification inside batch updates blocks or begin/end calls. That way the table will refresh when endUpdates is called, and not before. Basically form.removeAll removes from the data source and updates the table but it does not do it in one go. So the table sometimes thinks an item still exists in the data source when it doesn't, causing the crash.
@mats-claassen Have you seen the post above?
Hi @alexanderhenne, yes I have seen it. I haven't heard of any issues in a while.
As the Form does not have direct access to tableView or controller, the way you do it seems reasonable (as opposed to including that logic inside form. removeAll). Also it has to be noted that form.removeAll will eventually trigger a call to FormViewController.sectionsHaveBeenRemoved
and/or rowsHaveBeenRemoved
, which call beginUpdates and endUpdates around deleting sections/rows from the table (unless these functions are overridden and do not call super, or animateTableView
is set to False). So these might also be reasons for crashes I suppose
I am still getting this issue randomly on certain devices. Specifically on an iPhone 11 with iOS 17.7.0, the build was created with Xcode 16 with iOS 18 support.
Snippet of the crash log:
Last Exception Backtrace: 0 CoreFoundation 0x1a8292b28 exceptionPreprocess + 164 (NSException.m:249) 1 libobjc.A.dylib 0x1a010ef78 objc_exception_throw + 60 (objc-exception.mm:356) 2 CoreFoundation 0x1a81cafa4 -[NSArrayM objectAtIndex:] + 592 (NSArrayM.m:0) 3 Eureka 0x106e99e60 Form.subscript.getter + 20 (Form.swift:166) 4 Eureka 0x106e99e60 Form.subscript.getter + 156 (Form.swift:67) 5 Eureka 0x106e75f68 FormViewController.tableView(:didSelectRowAt:) + 192 (Core.swift:790) 6 Eureka 0x106e760bc @objc FormViewController.tableView(:didSelectRowAt:) + 120 (/
:0) 7 UIKitCore 0x1ab42fa80 -[UITableView _selectRowAtIndexPath:animated:scrollPosition:notifyDelegate:isCellMultiSelect:deselectPrevious:performCustomSelectionAction:] + 1232 (UITableView.m:9323) 8 UIKitCore 0x1ab42fdac -[UITableView _userSelectRowAtPendingSelectionIndexPath:animatedSelection:] + 268 (UITableView.m:9377) 9 UIKitCore 0x1ab42feac -[UITableView _userSelectRowAtPendingSelectionIndexPath:] + 216 (UITableView.m:9396) 10 UIKitCore 0x1aa4cd8f0 -[_UIAfterCACommitBlock run] + 72 (_UIAfterCACommitQueue.m:137) 11 UIKitCore 0x1aa4cd6d4 -[_UIAfterCACommitQueue flush] + 164 (_UIAfterCACommitQueue.m:228) 12 UIKitCore 0x1aa4cd5ec _runAfterCACommitDeferredBlocks + 496 (UIApplication.m:3123) 13 UIKitCore 0x1aa4cd378 _cleanUpAfterCAFlushAndRunDeferredBlocks + 100 (UIApplication.m:3087) 14 UIKitCore 0x1aa4b4a88 _afterCACommitHandler + 64 (UIApplication.m:3138) 15 CoreFoundation 0x1a81dbd3c CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION + 36 (CFRunLoop.c:1789) 16 CoreFoundation 0x1a81da738 CFRunLoopDoObservers + 552 (CFRunLoop.c:1902) 17 CoreFoundation 0x1a81d9e50 CFRunLoopRun + 1028 (CFRunLoop.c:2983) 18 CoreFoundation 0x1a81d9968 CFRunLoopRunSpecific + 608 (CFRunLoop.c:3420) 19 GraphicsServices 0x1ec4cf4e0 GSEventRunModal + 164 (GSEvent.c:2196) 20 UIKitCore 0x1aa64cedc -[UIApplication _run] + 888 (UIApplication.m:3692) 21 UIKitCore 0x1aa64c518 UIApplicationMain + 340 (UIApplication.m:5282) 22 Log Zero 0x104faef5c main + 64 (AppDelegate.swift:28) 23 dyld 0x1cb6fad84 start + 2240 (dyldMain.cpp:1298)
I'm unable to reproduce it but it keeps happening.
xcode 12.4 (12D4e) Eureka 5.3.3 iOS 14.4.2
basically we create the section once, then we have refresh our specific section by deleting all rows and recreating them. It might be trigger by viewDidAppear or Observers watching Realm
I've already tried to use both eureka removeAll functions.
removeAll(keepingCapacity keepCapacity: Bool = false)
public func removeAll(where shouldBeRemoved: (BaseRow) throws -> Bool) rethrows {
I've tried different aproches to refresh just the lines/section what we need to
The number of objects to add might be from 0 to 3
The last crash happen when the application was going to foreground.
i've also check:
2048
2141
it was already happening in the previous version we were using