iosobjective-cuint64nsuintegernsindexset

NSMutableIndexSet addIndex: Method Throws Error


In trying to delete some objects from Core Data, I am running into some difficulty using the NSMutableIndexSet class and it's method 'addIndex:'.

In core data I have folder objects, which contain a set of thread objects. Each thread has a threadId attribute which is a uint64_t. I am trying to create a mutable index set of these thread ids so that I can enumerate through them to delete their associated threads.

When I start trying to add my threadId's to my mutable index set, I get a crash with the following error:

[NSMutableIndexSet addIndexesInRange:]: Range {3982867280, 1} exceeds maximum index value of NSNotFound - 1'

This doesn't make sense since I am not calling the method 'addIndexesInRange:' as the error suggests.

Also, the 'addIndex:'takes an NSUInteger argument, but from what I'm reading, this should be interchangeable with the uint64_t.

Here is the code:

- (void)removeAllThreadsForFolder:(Folder *)folder
{
      NSError *error;
      NSArray *threads = [self fetchThreadsForFolder:folder error:&error];

      NSMutableIndexSet *threadIds = [NSMutableIndexSet new];

      for (Thread *thread in threads) {
          uint64_t threadId = thread.threadId; //the threadId does exist
          [threadIds addIndex:threadId]; //CRASH HERE!!!!!!!!!!!!!!!!!
      }

      [threadIds enumerateIndexesUsingBlock:^(NSUInteger threadId, BOOL *stop) {
          [self removeThreadForFolder:folder threadId:threadId]; 
      }];

      [self saveContext:&error];
      NSLog(@"folder now has %i threads", folder.threads.count);
}

Can anyone tell me what I am doing incorrectly and perhaps how to fix? Thanks


Solution

  • The NSMutableIndexSet addIndex: method expects a type of NSUInteger which is an unsigned long.

    When building a 32-bit app, this is a 32-bit value. When you build for 64-bit, it is a 64-bit value.

    Your threadId is a 64-bit value. Unless you are building a 64-bit iOS app, it is possible that many of the possible thread id values will be too large to fit in the 32-bit NSUInteger value, hence the error.

    Why are you using an index set to hold a set of thread ids? Why not use a NSMutableSet or NSMutableArray?

    Then you can do:

    NSMutableSet *threadIds = [NSMutableSet set];
    for (Thread *thread in threads) {
        uint64_t threadId = thread.threadId; //the threadId does exist
        [threadIds addObject:@(threadId)];
    }
    
    [threadIds enumerateObjectsUsingBlock:^(NSNumber *threadId, BOOL *stop) {
        [self removeThreadForFolder:folder threadId:[threadId unsignedLongLongValue]]; 
    }];