pronebird / UIScrollView-InfiniteScroll

UIScrollView ∞ scroll category
MIT License
1.06k stars 148 forks source link

Lots of crashes in pb_setContentOffset #64

Open cnordvik opened 6 years ago

cnordvik commented 6 years ago

http://crashes.to/s/2290ec3917a

Any idea why these crashes occur? We have 6000 crashes of these so would be nice to get to the root reason of it but I cannot see anything wrong in the code.

Crashed: com.apple.main-thread
0  libobjc.A.dylib                0x182185b9c objc_msgSend + 28
1  WebKit                         0x18aaf1e44 -[WKScrollViewDelegateForwarder forwardingTargetForSelector:] + 84
2  CoreFoundation                 0x182b128f4 ___forwarding___ + 112
3  CoreFoundation                 0x182a10c5c _CF_forwarding_prep_0 + 92
4  UIKit                          0x187f99568 -[UIScrollView(UIScrollViewInternal) _notifyDidScroll] + 76
5  UIKit                          0x187c8f0b4 -[UIScrollView setContentOffset:] + 460
6  UIScrollView_InfiniteScroll    0x1019f3cbc -[UIScrollView(InfiniteScroll) pb_setContentOffset:] (UIScrollView+InfiniteScroll.m:317)
7  WebKit                         0x18aafd0a0 -[WKWebView _processDidExit] + 388
8  WebKit                         0x18aa27f34 WebKit::WebPageProxy::resetStateAfterProcessExited() + 436
9  WebKit                         0x18aa2fc00 WebKit::WebPageProxy::processDidCrash() + 40
10 WebKit                         0x18aa7ead8 WebKit::WebProcessProxy::didClose(IPC::Connection&) + 256
11 JavaScriptCore                 0x1866ffba0 WTF::RunLoop::performWork() + 484
12 JavaScriptCore                 0x1867001fc WTF::RunLoop::performWork(void*) + 36
13 CoreFoundation                 0x182ac509c __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 24
14 CoreFoundation                 0x182ac4ab0 __CFRunLoopDoSources0 + 412
15 CoreFoundation                 0x182ac2830 __CFRunLoopRun + 724
16 CoreFoundation                 0x1829ecc50 CFRunLoopRunSpecific + 384
17 GraphicsServices               0x1842d4088 GSEventRunModal + 180
18 UIKit                          0x187cda088 UIApplicationMain + 204
pronebird commented 6 years ago

Hey,

Curious case. You don't activate infinite scroll for WKWebView right? Looking at the log it seems that something got over-released but I may be wrong.

If infinite scroll is not enabled for the WKWebView then pb_setContentOffset should only call super implementation. Looking at your trace the -[UIScrollView setContentOffset:] is actually being called so the crash happens somewhere down the road?

Do you know how to reproduce this crash?

cnordvik commented 6 years ago

That's the sad part, I've never seen the crash myself. We have a twitter timeline that is implemented by using UICollectionViewController.

I included some parts of the code. Can it be related to the fact that we may sometimes not call finishInfiniteScroll after addInfiniteScroll if something goes wrong in the network call?

public func loadTweets() {
        refreshControl.addTarget(self, action: #selector(reload), for: .valueChanged)
        collectionView?.addSubview(refreshControl)

        collectionView?.addInfiniteScroll(handler: { [weak self] scrollView in
            self?.refresh(load: .previous)
        })

        refresh(load: .reload)
    }

private func refresh(load: LoadType) {
        let sinceId: String?
        Logging.debug("Refreshing twitter feed! \(load)")
        switch load {
        case .previous:
            sinceId = loadedTweets.last?.tweetID
        default:
            sinceId = nil
        }

        matchDataSource.loadPreviousTweets(beforePosition: sinceId) { [weak self] tweets, cursor, error in
            guard let `self` = self else { return }

            switch ((tweets, cursor), error) {
            case ((let tweets?, _), _):
                self.updateTweets(tweets: tweets, load: load)
            case ((_, _), let error?):
                Logging.debug(error.localizedDescription)

                self.refreshControl.endRefreshing()
                self.collectionView?.finishInfiniteScroll()
            default:
                break
            }
        }
    }
pronebird commented 6 years ago

.finishInfiniteScroll only runs some animations and .addInfiniteScroll should only initialize once, all subsequent calls only update the handler block. So shouldn't matter in your case.

Is it possible that underlying UIScrollView somehow outlives WKWebView? Maybe you drop a reference to WKWebView somewhere too early or something?

I saw some errors related to _notifyDidScroll before and most of them were related to bad timing in UIKit.

I can only guess at this point, the last call in stack trace is related to WKScrollViewDelegateForwarder, I don't think UIScrollView+InfiniteScroll causes the crash per se.

The crash log you shared points to WKWebView, so I don't think it's related to UICollectionView that you use. It could be that you display the WKWebView inside of cell that's being reused, so maybe you need to clean up WKWebView when cell goes out of view or being reused..

Ariandr commented 1 year ago

Have the same issue