5

Hi there,

In my app, I create NSOperations and I add them to a NSOperationQueue. Sometimes, I want to cancel some specific operations from my operation queue, that's why I have defined an identifier property for my NSOperation subclass :

@property (nonatomic, assign) NSString *identifier;

But when I loop into my queue's operations and I want to compare my operation's identifier to the identifier of the operation I want to fetch, I got an EXC_BAD_ACCESS pointing out the if condition:

for (MyCustomNSOperationClass *operation in self.myOperationQueue.operations)
{
     NSString *identifier = [self getRelatedIdentifier];
     if ([operation.identifier isEqualToString:identifier])
     {
           [operation cancel];
     }
}

The operation's identifier should be something like 33a37fb0-8f77-0132-6c0b-5254005d9147 but when it crashes, it's something like 0x7be4af00 ( when I use po operation.identifier ). I say when it crashes, because it doesn't always crash and when it doesn't crash, then the identifier is correct ( I'm not sure to be super clear... ).

As I am new with NSOperation, I wanted to know if there was an other way to achieve what I'd like to do ?

Thanks in advance !

Randy
  • 4,335
  • 3
  • 30
  • 64

2 Answers2

1

It is better to have an array operations:[MyCustomNSOperationClass] (or dictionary operations:[String: MyCustomNSOperationClass] ) that keeps references to all operations in the queue and then you cancel it directly without searching for it in the queue.

Ismail
  • 2,778
  • 2
  • 24
  • 39
1

Your issue was that you do not take a copy of the operation and the queue might be modified in the time of your loop.

  NSArray<MyCustomNSOperationClass *> *operations = operationQueue.operations.copy;

  for (MyCustomNSOperationClass *operation in operations) {

    if (!operation.isFinished && [operation.identifier isEqualToString:self.cancelIdentifier]) {
      [operation cancel];
    }

  }

You shouldn't rely on the state of the OperationQueue to perform your actions and storing it in a dictionary as Ismail suggested would be a viable solution.

Oliver Atkinson
  • 7,970
  • 32
  • 43