Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/96.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 设置完成时取消NSO操作EXC\u错误\u访问崩溃_Ios_Objective C_Exc Bad Access_Key Value Observing_Nsoperation - Fatal编程技术网

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你找到了这个问题的答案,你还记得吗?