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

SwiftUI KVO Crash #1589

Open
LuckyCat7848 opened this issue Aug 2, 2023 · 0 comments
Open

SwiftUI KVO Crash #1589

LuckyCat7848 opened this issue Aug 2, 2023 · 0 comments
Labels

Comments

@LuckyCat7848
Copy link

必现/偶发?
必现

怎么样重现这个bug

  1. 把 MJRefreshFooter 使用 UIViewRepresentable 包装成 SwiftUI 中可以使用的 View;
  2. 在 SwiftUI 页面使用加载,页面返回销毁。此时崩溃在 MJRefreshComponent line 105 removeObservers() 方法中。
    崩溃日志:
    *** Terminating app due to uncaught exception 'NSRangeException', reason: 'Cannot remove an observer <MJRefreshBackNormalFooter 0x126b7e7b0> for the key path "contentOffset" from <TtGC7SwiftUI16PlatformViewHostGVS_P10$1c8b6b12832PlatformViewRepresentableAdaptorV9JKSwiftUI26SwiftUIMJRefreshFooterView_ 0x126b7f3d0> because it is not registered as an observer.'

分析原因:

  1. 在这里 self.superview 移除KVO监听时,移除的是 contentOffset 和 contentSize,而SwiftUI场景走到这里的 self.superView 不是UIScrollView的子类,没有添加这两个属性及监听,因此崩溃。
  • (void)removeObservers
    {
    [self.superview removeObserver:self forKeyPath:MJRefreshKeyPathContentOffset];
    [self.superview removeObserver:self forKeyPath:MJRefreshKeyPathContentSize];
    [self.pan removeObserver:self forKeyPath:MJRefreshKeyPathPanState];
    self.pan = nil;
    }

解决建议:

  1. 这里移除KVO的时候判断一下:
    if (self.superview && ![self.superview isKindOfClass:[UIScrollView class]]) return;

运行环境

  • iPhone12
  • iOS15.4
  • Xcode14.2
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant