Reputation: 6947
I have an iOS app with a keyframe animation. Once the last keyframe is about to finish, my app crashes with this error:
*** Terminating app due to uncaught exception 'NSRangeException',
reason: '*** -[__NSArrayM objectAtIndex:]: index 4294967295 beyond
bounds for empty array'
I have the suspicion that maybe this is a problem of unintentionally nesting animations. Did anybody ever run into a problem like this?
If I replace the keyframe animation with a normal animation block, the app does not crash.
Inside the keyframe animation I change the content offset of a scroll view and a few other things. I added objc message logging, but even this did not give a clue why this happens.
Full stack trace:
*** First throw call stack:
(
0 CoreFoundation 0x021b15e4 __exceptionPreprocess + 180
1 libobjc.A.dylib 0x01b968b6 objc_exception_throw + 44
2 CoreFoundation 0x021524e6 -[__NSArrayM objectAtIndex:] + 246
3 UIKit 0x0095288d __35-[UIViewKeyframeAnimationState pop]_block_invoke_3 + 415
4 CoreFoundation 0x0222e446 __53-[__NSArrayM enumerateObjectsWithOptions:usingBlock:]_block_invoke + 102
5 CoreFoundation 0x0222e352 -[__NSArrayM enumerateObjectsWithOptions:usingBlock:] + 290
6 CoreFoundation 0x021ab0a5 -[NSArray enumerateObjectsUsingBlock:] + 53
7 UIKit 0x009524e7 __35-[UIViewKeyframeAnimationState pop]_block_invoke + 518
8 CoreFoundation 0x0223b13a __65-[__NSDictionaryM enumerateKeysAndObjectsWithOptions:usingBlock:]_block_invoke + 106
9 CoreFoundation 0x0223b03e -[__NSDictionaryM enumerateKeysAndObjectsWithOptions:usingBlock:] + 190
10 CoreFoundation 0x0219f525 -[NSDictionary enumerateKeysAndObjectsUsingBlock:] + 53
11 UIKit 0x00952268 -[UIViewKeyframeAnimationState pop] + 385
12 UIKit 0x0094f336 +[UIViewAnimationState popAnimationState] + 47
13 UIKit 0x0096729a +[UIView(UIViewAnimationWithBlocks) _setupAnimationWithDuration:delay:view:options:factory:animations:start:animationStateGenerator:completion:] + 508
14 UIKit 0x009688b9 +[UIView(UIViewKeyframeAnimations) animateKeyframesWithDuration:delay:options:animations:completion:] + 163
Update: (relevant code)
I stepped through the code in the debugger. The animation block completes fine. As soon as I step over the line to enter the completion block the crash happens.
It only crashes when I set the start time to > 0.
The array in question seems to be part of the animation stack, not one of my own arrays (none are accessed during my animation code).
Is there a way to dump the UIView animation state?
[UIView animateKeyframesWithDuration:1.0 delay:0.0 options:0 animations:^{
[UIView addKeyframeWithRelativeStartTime:0.1 relativeDuration:0.9 animations:^{
snapshot.center = snapshotAwayCenter;
snapshot.transform = rotateOutTransform;
CGFloat pageOffset = ...// calculate page offset
self.scrollView.contentOffset = CGPointMake(pageOffset, 0.0);
// block returns (stepped through in debugger)
}];
} completion:^(BOOL finished){ // When stepping over this line, the crash happens
// more stuff here
}];
Upvotes: 3
Views: 1845
Reputation: 4735
The crash is not due to the UIView's addKeyframeWithRelativeStartTime: method.
It is occurring due to you accessing an element in an array which exceeds the number of items in the array. Looking at your code I cannot see where you are using an array, but rest assured that you are doing it somewhere (probably in code that you have neglected to post).
Due to the apparent accessed index: 4294967295 you are obviously trying to access the element at the index -1 but it is unsigned, and so appears as 4294967295.
Upvotes: 2