-
Notifications
You must be signed in to change notification settings - Fork 3.5k
Open
Labels
Description
必现/偶发?
必现
怎么样重现这个bug
- 把 MJRefreshFooter 使用 UIViewRepresentable 包装成 SwiftUI 中可以使用的 View;
- 在 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.'
分析原因:
- 在这里 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;
}
解决建议:
- 这里移除KVO的时候判断一下:
if (self.superview && ![self.superview isKindOfClass:[UIScrollView class]]) return;
运行环境
- iPhone12
- iOS15.4
- Xcode14.2