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

Internal inconsistency exception when scrolling #2189

Open
rph8 opened this issue Nov 23, 2021 · 5 comments
Open

Internal inconsistency exception when scrolling #2189

rph8 opened this issue Nov 23, 2021 · 5 comments

Comments

@rph8
Copy link

rph8 commented Nov 23, 2021

Hi everyone,

I am using the latest Eureka and seem to run into internal inconsistency exceptions caused by a .cellUpdate.
It seems to be related to an issue described on Apple's forums: https://developer.apple.com/forums/thread/92132 (there is no solution documented there).
Whenever I scroll the view, the internal inconsistency exception (see stack trace below) is raised, causing a crash. Without scrolling I can also sometimes see the exception in the log, but it somehow does not lead to a crash.

Environment: Eureka 5.3.4, Xcode 13.1 and iOS 15.0.2

So my code looks roughly like this:

retrieveSection()  <<< TextAreaRow() { row in
        row.tag = "someTag"
        row.title = "someTitle"
        row.baseCell.isUserInteractionEnabled = false
        row.hidden = false
        row.value = "someString"
        
    }.cellUpdate({ (cell, row) in
        cell.textLabel?.textColor = UIColor.blue
        cell.textLabel?.font = someFont
        
        cell.textView.font = someOtherFont
        cell.textView.textColor = UIColor.green
        
        cell.tintColor = UIColor.black
        
        guard let htmlData = htmlString.data(using: String.Encoding.utf8, allowLossyConversion: true) else {
            return nil
        }
        
        guard let someHTMLAsAttributedString = try? NSAttributedString(data: data,
                                      options: [.documentType: NSAttributedString.DocumentType.html,
                                                .characterEncoding: String.Encoding.utf8.rawValue],
                                                                       documentAttributes: nil) else {
            return nil
        }
        
        cell.textView.attributedText = someHTMLAsAttributedString
                    
        cell.height = { cell.textView.contentSize.height }
        
        cell.isUserInteractionEnabled = false
    })

And here is the exception + stack trace that I get:

Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'UITableView internal inconsistency: _visibleRows and _visibleCells must be of same length. _visibleRows: {0, 9}; _visibleCells.count: 20, _visibleCells: (
"<Eureka.TextAreaCell: 0x1071f4800; baseClass = UITableViewCell; frame = (0 35; 359 368); autoresize = W; userInteractionEnabled = NO; tintColor = UIExtendedSRGBColorSpace 0 0 0 1; layer = <CALayer: 0x2821a5a20>>",
"<Eureka.TextAreaCell: 0x10720d800; baseClass = UITableViewCell; frame = (0 403; 359 60); autoresize = W; userInteractionEnabled = NO; tintColor = UIExtendedSRGBColorSpace 0 0 0 1; layer = <CALayer: 0x2821b9e00>>",
"<TtGC6Eureka17AlertSelectorCellSS: 0x107174200; baseClass = UITableViewCell; frame = (0 463; 359 44); text = 'some text'; autoresize = W; tintColor = UIExtendedSRGBColorSpace 0 0 0 1; layer = <CALayer: 0x282152320>>",
"<TtGC6Eureka17AlertSelectorCellSS: 0x107214c00; baseClass = UITableViewCell; frame = (0 507; 359 44); text = 'some text'; autoresize = W; tintColor = UIExtendedSRGBColorSpace 0 0 0 1; layer = <CALayer: 0x282152680>>",
"<TtGC6Eureka11LabelCellOfSS: 0x10720fc00; baseClass = UITableViewCell; frame = (0 551; 359 44); text = 'some text'; autoresize = W; layer = <CALayer: 0x282153940>>",
"<TtGC6Eureka13SegmentedCellSS: 0x1071a7800; baseClass = UITableViewCell; frame = (0 595; 359 44); autoresize = W; tintColor = UIExtendedSRGBColorSpace 0.603922 0.239216 0.215686 1; layer = <CALayer: 0x28215c740>>",
"<TtGC6Eureka11LabelCellOfSS: 0x10c043000; baseClass = UITableViewCell; frame = (0 639; 359 44); text = 'some text'; autoresize = W; layer = <CALayer: 0x282154660>>",
"<Eureka.TextCell: 0x10c248000; baseClass = UITableViewCell; frame = (0 683; 359 44); autoresize = W; tintColor = UIExtendedSRGBColorSpace 0 0 0 1; layer = <CALayer: 0x2821557c0>>",
"<Eureka.TextAreaCell: 0x10c231a00; baseClass = UITableViewCell; frame = (0 727; 359 60); autoresize = W; userInteractionEnabled = NO; tintColor = UIExtendedSRGBColorSpace 0 0 0 1; layer = <CALayer: 0x282156240>>",
"<Eureka.TextAreaCell: 0x1071f4800; baseClass = UITableViewCell; frame = (0 35; 359 368); autoresize = W; userInteractionEnabled = NO; tintColor = UIExtendedSRGBColorSpace 0 0 0 1; layer = <CALayer: 0x2821a5a20>>",
"<Eureka.TextAreaCell: 0x10720d800; baseClass = UITableViewCell; frame = (0 403; 359 60); autoresize = W; userInteractionEnabled = NO; tintColor = UIExtendedSRGBColorSpace 0 0 0 1; layer = <CALayer: 0x2821b9e00>>",
"<TtGC6Eureka17AlertSelectorCellSS: 0x107174200; baseClass = UITableViewCell; frame = (0 463; 359 44); text = 'some text'; autoresize = W; tintColor = UIExtendedSRGBColorSpace 0 0 0 1; layer = <CALayer: 0x282152320>>",
"<TtGC6Eureka17AlertSelectorCellSS: 0x107214c00; baseClass = UITableViewCell; frame = (0 507; 359 44); text = 'some text'; autoresize = W; tintColor = UIExtendedSRGBColorSpace 0 0 0 1; layer = <CALayer: 0x282152680>>",
"<TtGC6Eureka11LabelCellOfSS: 0x10720fc00; baseClass = UITableViewCell; frame = (0 551; 359 44); text = 'some text'; autoresize = W; layer = <CALayer: 0x282153940>>",
"<TtGC6Eureka13SegmentedCellSS: 0x1071a7800; baseClass = UITableViewCell; frame = (0 595; 359 44); autoresize = W; tintColor = UIExtendedSRGBColorSpace 0.603922 0.239216 0.215686 1; layer = <CALayer: 0x28215c740>>",
"<TtGC6Eureka11LabelCellOfSS: 0x10c043000; baseClass = UITableViewCell; frame = (0 639; 359 44); text = 'some text'; autoresize = W; layer = <CALayer: 0x282154660>>",
"<Eureka.TextCell: 0x10c248000; baseClass = UITableViewCell; frame = (0 683; 359 44); autoresize = W; tintColor = UIExtendedSRGBColorSpace 0 0 0 1; layer = <CALayer: 0x2821557c0>>",
"<Eureka.TextAreaCell: 0x10c231a00; baseClass = UITableViewCell; frame = (0 727; 359 60); autoresize = W; userInteractionEnabled = NO; tintColor = UIExtendedSRGBColorSpace 0 0 0 1; layer = <CALayer: 0x282156240>>",
"<Eureka.TextCell: 0x107268a00; baseClass = UITableViewCell; frame = (0 787; 359 5); hidden = YES; autoresize = W; userInteractionEnabled = NO; layer = <CALayer: 0x282144a00>>",
"<Eureka.TextAreaCell: 0x10726aa00; baseClass = UITableViewCell; frame = (0 792; 359 60); hidden = YES; autoresize = W; userInteractionEnabled = NO; tintColor = UIExtendedSRGBColorSpace 0 0 0 1; layer = <CALayer: 0x282147cc0>>"
)'
terminating with uncaught exception of type NSException

Any ideas why this leads to a crash?

@mats-claassen
Copy link
Member

Hi, a quick try could be to remove row.baseCell.isUserInteractionEnabled = false from the row initializer and moving it to either cellSetup or cellUpdate. The cell should not be accessed in the row initializer because it will lead to the cell being instantiated at the wrong time.

@rph8
Copy link
Author

rph8 commented Dec 19, 2021

Hey @mats-claassen, thanks for the idea. Unfortunately, that did not help. Simply moving that line into the update and not accessing row.baseCell from the row initializer did not solve issue. The exception-triggered crash persists as before.
Any other ideas?

@rph8
Copy link
Author

rph8 commented Dec 19, 2021

@mats-claassen It seems that patching Row.swift regarding the updateCell either solves or at least masks the problem.

So if we change

override open func updateCell() {
        super.updateCell()
        cell.update()
        customUpdateCell()
        RowDefaults.cellUpdate["\(type(of: self))"]?(cell, self)
        callbackCellUpdate?()
}

into

override open func updateCell() {
        super.updateCell()
        DispatchQueue.main.async { [weak self] in
            guard let self = self else { return }
            self.cell.update()
            self.customUpdateCell()
            RowDefaults.cellUpdate["\(type(of: self))"]?(self.cell, self)
            self.callbackCellUpdate?()
        }
}

So mainly moving the cellUpdate from a that function directly into a subsequent main loop run seems to do the trick.
Do you know why?
Should this be patched in Eureka?

@rph8
Copy link
Author

rph8 commented Dec 19, 2021

Opened a pull request for the proposed fix: #2195

@mats-claassen
Copy link
Member

I don't think this is a good way to fix an issue unless there is really no way to fix it from the user side. It seems weird that this is not something happening normally when using cellUpdate and I haven't seen any similar issue reported by someone else.

I also couldn't reproduce that crash. Some new comments regarding your code: Try setting textAreaMode to readOnly instead of setting userInteractionEnabled. You can also experiment with textAreaHeight instead of setting the height directly.
If that doesn't change anything then please make sure there is no other part of your code modifying the form while these updates happen.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants