Ios 设置完成时取消NSO操作EXC\u错误\u访问崩溃
我有一个Ios 设置完成时取消NSO操作EXC\u错误\u访问崩溃,ios,objective-c,exc-bad-access,key-value-observing,nsoperation,Ios,Objective C,Exc Bad Access,Key Value Observing,Nsoperation,我有一个NSOperation子类,它从UITableView运行异步操作 我覆盖了正确的开始和结束方法,如下所示: - (void)start { [self willChangeValueForKey:@"isExecuting"]; self.isExecuting = YES; [self didChangeValueForKey:@"isExecuting"]; if (self.isCancelled) { [self fin
NSOperation
子类,它从UITableView
运行异步操作
我覆盖了正确的开始和结束方法,如下所示:
- (void)start
{
[self willChangeValueForKey:@"isExecuting"];
self.isExecuting = YES;
[self didChangeValueForKey:@"isExecuting"];
if (self.isCancelled)
{
[self finish];
return;
}
}
- (void)finish
{
if (!_isExecuting)
{
[self willChangeValueForKey:@"isExecuting"];
_isExecuting = YES;
[self didChangeValueForKey:@"isExecuting"];
}
[self willChangeValueForKey:@"isExecuting"];
[self willChangeValueForKey:@"isFinished"];
_isExecuting = NO;
_isFinished = YES;
[self didChangeValueForKey:@"isExecuting"];
[self didChangeValueForKey:@"isFinished"];
}
我遇到的问题是,如果我向下滚动表格并删除一行,这将调用操作上的cancel
方法,但是,随着操作逐渐完成,它到达表格的更深处,它会在[self-didChangeValueForKey:@“isFinished”]行上出现EXC\u BAD\u ACCESS
错误而崩溃代码>
将代码粘贴到这里非常复杂,但我想知道的是,如何跟踪导致KVO消息崩溃的对象
如果我在调试器中启用zombie对象,它根本不会崩溃,没有任何警告,这是没有帮助的
如果我将KVO方法包装在try/catch
中,它将永远不会被捕获,并且仍然会崩溃
我已尝试在我的NSOperation
子类中重写KVO方法,但从未调用它们:
- (void)addObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(void *)context
{
NSLog(@"%s - %@", __PRETTY_FUNCTION__, observer);
[super addObserver:observer forKeyPath:keyPath options:options context:context];
}
有可能看到谁是观察员吗?评论和想法:
在start
中,不应self.isExecuting=YES
be\u isExecuting=YES代码>
添加一个NSString类型的名为identifier
的属性,并为每个操作设置它
添加一个dealloc
方法并记录标识符
在中,完成测试是否已取消
,如果已取消,请立即返回
另一个想法是双重保留操作—将它们放在NSDictionary中,以标识符作为键,然后查看是否有任何更改。我遇到了同样的问题。
之所以发生这种情况,是因为您在调用start方法之前设置了isFinished变量的值
要解决此问题,需要在cancel方法中设置标志isCancelled=YES(且仅限)。
在方法中,开始检查取消状态
如果操作在启动前已取消,则应已设置以下值:
self.executing = YES;
self.executing = NO;
self.finished = YES;
所有代码:
-(void)start
{
if ((self.ready == YES) && (self.executing == NO) && ((self.finished == NO)) // if Ready To Start State
{
self.ready = NO; self.executing = YES; self.finished = NO; // Setting Working State
[self receiveItemAtURL:self.url params:self.params
timeStoreExpire:self.storageTime
progress:self.operationProgressBlock
completion:self.operationCompletionBlock];
}else if ((self.ready == NO) && (self.cancelled == YES){ // If Cancelled State
self.executing = YES;
self.executing = NO;
self.finished = YES;
}
}
- (void) cancel
{
if ((self.ready == YES) && (self.executing == NO) && ((self.finished == NO)) { // If Working State
self.ready = NO; self.cancelled = YES; // Setting Cancelled State
}
else if ((self.ready == NO) && (self.executing == YES) && (self.finished == NO) || // If Working State
(self.ready == YES) && (self.executing == NO) && (self.finished == NO)) // If Suspend State
{
self.state = RXCOCancelled;
self.executing = YES;
self.executing = NO;
self.finished = YES;
}
}
1、谢谢。2&3我使用了indepath
并删除了indepath 4-14,它立即取消并解除了NSOperation
。就在操作队列4-9完成后,它崩溃了。从我对苹果文档的理解来看,即使是取消的操作也要先开始,然后完成。所以它一定是在尝试4-14开始,但由于它被释放,我不知道它怎么会在finish方法上崩溃。我已经很久没有使用NSOperations了-它一出来,我就切换到GCD。你为什么不试试4?它可能是你试图改变后,取消属性造成的问题…我想我已经修复了它,它与4。在cancel方法中,我手动调用finished方法。我确信我在某个地方读到过这样做的内容,因为cancel方法只是简单地翻转isCancelled
bool。移除那个似乎已经停止了崩溃的ID你找到了这个问题的答案,你还记得吗?