gpt4 book ai didi

ios - KVO 消息发送到已释放实例错误。即使观察者被移除

转载 作者:行者123 更新时间:2023-12-01 19:00:32 27 4
gpt4 key购买 nike

我需要检测 tableview contentOffset 的变化,所以我使用了 KVO,一切正常。在同一个 View Controller 中,我也有一个 UIActivityViewController 服务。
如果我使用来自 uiactivityviewcontroller 的服务,然后在被解雇后,我弹出 View Controller ,我会收到以下错误...

* frame #0: 0x0000000183071280 CoreFoundation`___forwarding___ + 736
frame #1: 0x0000000182f9108c CoreFoundation`__forwarding_prep_0___ + 92
frame #2: 0x0000000183b2e7d0 Foundation`NSKeyValuePushPendingNotificationPerThread + 340
frame #3: 0x0000000183b19068 Foundation`NSKeyValueWillChange + 532
frame #4: 0x0000000183b023a8 Foundation`-[NSObject(NSKeyValueObserverNotification) willChangeValueForKey:] + 236
frame #5: 0x0000000183bc9148 Foundation`_NSSetPointValueAndNotify + 116
frame #6: 0x00000001863126c0 UIKit`-[UIScrollView(UIScrollViewInternal) _adjustContentOffsetIfNecessary] + 864
frame #7: 0x0000000186116a0c UIKit`-[UIScrollView(UIScrollViewInternal) _stopScrollingNotify:pin:tramplingDragFlags:] + 352
frame #8: 0x0000000186116864 UIKit`-[UIScrollView removeFromSuperview] + 44
frame #9: 0x000000018603377c UIKit`-[UIView dealloc] + 424
frame #10: 0x0000000182f69ad4 CoreFoundation`CFRelease + 468
frame #11: 0x0000000182f75ec0 CoreFoundation`-[__NSArrayM dealloc] + 156
frame #12: 0x000000018f58d474 libobjc.A.dylib`(anonymous namespace)::AutoreleasePoolPage::pop(void*) + 524
frame #13: 0x0000000182f6d438 CoreFoundation`_CFAutoreleasePoolPop + 28
frame #14: 0x000000018302c974 CoreFoundation`__CFRunLoopRun + 1460
frame #15: 0x0000000182f6d6d0 CoreFoundation`CFRunLoopRunSpecific + 452
frame #16: 0x0000000188c51c0c GraphicsServices`GSEventRunModal + 168
frame #17: 0x000000018609efdc UIKit`UIApplicationMain + 1156

要添加或删除 kvo,我使用以下行
- (void)viewWillAppear:(BOOL)animated
{
[self.tableView addObserver:self forKeyPath:@"contentOffset" options:NSKeyValueObservingOptionNew context:NULL];
}

- (void)viewWillDisappear:(BOOL)animated
{
[self.tableView removeObserver:self forKeyPath:@"contentOffset"];
}

最佳答案

您可能应该有一个 state 属性来跟踪您是否添加了观察者。您可能看不到 viewWillDisappear当您的事件 View 指示器 Controller 出现时,即使您可能会看到 viewWillAppear当您返回时再次调用。因此,当您关闭 View Controller 时,您添加了两次观察者,但只删除了一次。

放一些NSLog声明,我打赌你会发现你对 viewWillDisappear 的调用和 viewWillAppear不平衡(不是你自己的错)。结果,我敢打赌,您添加观察者的次数比删除它的次数要多。

通过添加状态属性,observingContentOffset ,你可以解决这个问题:

@property (nonatomic) BOOL observingContentOffset;

然后,您可以让添加和删除观察者的代码检查此属性:
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated]; // don't forget to call super

if (!self.observingContentOffset) {
[self.tableView addObserver:self forKeyPath:@"contentOffset" options:NSKeyValueObservingOptionNew context:NULL];
self.observingContentOffset = YES;
}
}

- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated]; // don't forget to call super

if (self.observingContentOffset) {
[self.tableView removeObserver:self forKeyPath:@"contentOffset"];
self.observingContentOffset = NO;
}
}

虽然上述内容应该可以解决您的问题,但我会更进一步,建议您考虑完全停用此 KVO 代码。由于 tableview 实际上是 ScrollView 的子类,因此当您设置 table view 的委托(delegate)时,您还指定了底层 ScrollView 的委托(delegate)。因此,指定表格 View 的委托(delegate)后,它也将用作 ScrollView 委托(delegate),您可以简单地实现相关的 UIScrollViewDelegate 方法)。如果您需要识别每个滚动事件,这可能是一种比 KVO 更强大的技术(巧合的是,它也消除了您最初的问题)。如果你只需要识别何时从 View 中删除单元格,iOS 6 提供了一些相关的高级 UITableViewDelegate 使其更容易的方法。

关于ios - KVO 消息发送到已释放实例错误。即使观察者被移除,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23205969/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com