Search code examples
objective-ciosmultithreadingnsmutablearray

Is Objective-C's NSMutableArray thread-safe?


I've been trying to fix this crash for almost a week. The application crashes without any exception or stack-trace. The application does not crash in any way while running through instruments in zombie mode.

I have a method that gets called on a different thread. The solution that fixed the crash was replacing

[self.mutableArray removeAllObjects];

with

dispatch_async(dispatch_get_main_queue(), ^{
    [self.searchResult removeAllObjects];
});

I thought it might be a timing issue, so I tried to synchronize it, but it still crashed:

@synchronized(self)
{
    [self.searchResult removeAllObjects];
}

Here is the code

- (void)populateItems
{
   // Cancel if already exists  
   [self.searchThread cancel];

   self.searchThread = [[NSThread alloc] initWithTarget:self
                                               selector:@selector(populateItemsinBackground)
                                                 object:nil];

    [self.searchThread start];
}


- (void)populateItemsinBackground
{
    @autoreleasepool
    {
        if ([[NSThread currentThread] isCancelled])
            [NSThread exit];

        [self.mutableArray removeAllObjects];

        // Populate data here into mutable array

        for (loop here)
        {
            if ([[NSThread currentThread] isCancelled])
                [NSThread exit];

            // Add items to mutableArray
        }
    }
}

Is this problem with NSMutableArray not being thread-safe?


Solution

  • No.

    It is not thread safe and if you need to modify your mutable array from another thread you should use NSLock to ensure everything goes as planned:

    NSLock *arrayLock = [[NSLock alloc] init];
    
    [...] 
    
    [arrayLock lock]; // NSMutableArray isn't thread-safe
    [myMutableArray addObject:@"something"];
    [myMutableArray removeObjectAtIndex:5];
    [arrayLock unlock];