Hi everyone,

I'm getting an EXC_BAD_ACCESS from my specific combination of
performBatchUpdates: and removeObjectAtIndex:.

The application is within a framework I'm developing. The framework has a
Mediator object, and multiple Manager dependencies. The Mediator combines
input from all of the Managers in order to control a single
UICollectionView.

Inside the Mediator exists a custom Counter class. The Counter's
implementation is mostly irrelevant, except that it is ultimately backed by
an NSArray.

Here's some code:

FOOMediator.m
```
@interface FOOMediator ()
@property (nonatomic) FOOCounter *counter;
@end

@implementation FOOMediator

- (void)manager:(FOOManager *)manager batchDeleteIndexPaths:(NSArray
*)indexPaths
{
    [self.collectionView performBatchUpdates:^{
        for (NSIndexPath *indexPath in indexPaths) {
            [self manager:manager removeItemAtIndexPath:indexPath];
        }
    } completion:nil];
}

- (void)manager:(FOOManager *)manager removeItemAtIndexPath:(NSIndexPath
*)indexPath
{
    NSString *key = [self keyForManager:manager];

    NSUInteger globalIndex = [self.counter
globalIndexForLocalizedIndex:indexPath.item forKey:key];
    NSIndexPath *globalIndexPath = [NSIndexPath
indexPathForItem:globalIndex inSection:0];

    [self.counter removeKeyAtIndex:globalIndex]; // COMMENTING OUT THIS
LINE STOPS THE EXC_BAD_ACCESS!
    [self.collectionView deleteItemsAtIndexPaths:@[globalIndexPath]];
}

@end
```

FOOCounter.m
```
@interface FOOCounter ()
@property (nonatomic) NSMutableArray *keys;
@end

@implementation FOOCounter

- (void)removeKeyAtIndex:(NSUInteger)index
{
    [self.keys removeObjectAtIndex:index];
}

@end
```

The problem arises when a Manager attempts to batch insert + batch delete
sets of items multiple times, in quick succession.

In this situation, an EXC_BAD_ACCESS is thrown, caused by the line noted
above ([self.counter removeKeyAtIndex...]). If I uncomment that line, the
exception stops getting thrown, and everything works.

Enabling Guard Malloc reports, on the line of performBatchUpdates, a buffer
underrun situation:
```
GuardMalloc[Foobar-62390]: free: header for block 0x12001ecff0-0x12001ed000
has been trashed by a buffer underrun. Header magic value at 0x12001ecfe8
is 0x0000000000000009, not 0xdeadbeefdeadbeef.  Try running with
MALLOC_PROTECT_BEFORE to catch this error immediately as it happens.
```
...and running with MALLOC_PROTECT_BEFORE will also break on
performBatchUpdates:.

Could anyone offer any suggestions as to why this is happening? Any ideas
how to mitigate this? Thanks in advanced for any help!

-Josh
_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to