performBatchUpdates: + removeObjectAtIndex: = EXC_BAD_ACCESS
performBatchUpdates: + removeObjectAtIndex: = EXC_BAD_ACCESS
- Subject: performBatchUpdates: + removeObjectAtIndex: = EXC_BAD_ACCESS
- From: Josh Avant <email@hidden>
- Date: Fri, 16 Jan 2015 20:38:26 -0800
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 (email@hidden)
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:
This email sent to email@hidden