UIView animateWithDuration causes app to crash

0

My snippet of code is given below. This causes the app to crash. Curiously, the app only crashes when I create an archive and load the archive on my device. If I run it on the device straight from XCode, it runs fine.

for (int i = 0; i < 8; i++) {
    for (int j = 0; j < 12; j++) {
        UILabel *label = (UILabel *)[self.view viewWithTag:((j+1) * 10 + (i+1))];
        [UIView animateWithDuration:1.0
                         animations:^{
                             label.alpha = 0.0f;
                             label.text = [cryptograms objectAtIndex:i * 12 + j];
                             label.alpha = 1.0f;
                         }];
    }
}

If I however, create an archive using the following code snippet, it works fine.

for (int i = 0; i < 8; i++) {
    for (int j = 0; j < 12; j++) {
        UILabel *label = (UILabel *)[self.view viewWithTag:((j+1) * 10 + (i+1))];
        [label setText:[cryptograms objectAtIndex:i * 12 + j]];

    }
}

I have verified that the problem is not the size of the array. The array always has 96 elements. The crash log shows the following..

Exception Type:  EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: KERN_INVALID_ADDRESS at 0x00000017
Crashed Thread:  0

Thread 0 name:  Dispatch queue: com.apple.main-thread
Thread 0 Crashed:
0   libobjc.A.dylib                 0x37148584 _cache_getImp + 4
1   libobjc.A.dylib                 0x37148fa0 lookUpMethod + 24
2   libobjc.A.dylib                 0x3714a1e2 class_respondsToSelector + 26
3   CoreFoundation                  0x382c3638 ___forwarding___ + 372
4   CoreFoundation                  0x3821b204 _CF_forwarding_prep_0 + 20
5   GridSoftToken                   0x000990ae __41-[ViewController updateCryptogramLabels:]_block_invoke_0 (ViewController.m:69)
6   UIKit                           0x375bae80 +[UIView(UIViewAnimationWithBlocks) _setupAnimationWithDuration:delay:view:options:animations:start:completion:] + 492
7   UIKit                           0x37672172 +[UIView(UIViewAnimationWithBlocks) animateWithDuration:animations:] + 54
8   GridSoftToken                   0x0009903c -[ViewController updateCryptogramLabels:] (ViewController.m:66)
9   GridSoftToken                   0x00098dc2 -[ViewController viewDidAppear:] (ViewController.m:44)
10  UIKit                           0x3760b2c8 -[UIViewController _setViewAppearState:isAnimating:] + 132
11  UIKit                           0x37627f24 -[UIViewController _executeAfterAppearanceBlock] + 48

Any ideas on how I can troubleshoot this issue ? I can obviously get rid of the animation, but I would like to keep it in place.

ios
animation
uiview
segmentation-fault
asked on Stack Overflow Nov 12, 2012 by abu.marcose

2 Answers

1

1: Put your logic inside the animation block and not vice versa.

SIGSEV means that your program tries to read or write outside the memory that is allocated for it. It's hard for me to see the reason for it in your code. I could be something with the tags or the scope of the animation gets somehow mixed up since you creating a lot of simultaneous animations.

2: Your alpha change code...

label.alpha = 0.0f;
label.alpha = 1.0f;

... won't have any affect since you change the alpha in the same animation.
If you wan't to set it back to 1.0f then do that in the completion block.

answered on Stack Overflow Nov 12, 2012 by yinkou
0

Using @yinkou's suggestion of putting the logic within the animation block, I re-worked the code and now it runs without any issues.Attaching the revised code below for reference. Hopefully it will help somebody else. I am still not sure why this works and the previous version does not, but like @yinkou suggested, maybe it has something to do with the large number of simultaneous animations!!

[UIView animateWithDuration:1.0
                 animations:^{
                     for (int i = 0; i < 8; i++) {
                         for (int j = 0; j < 12; j++) {
                             UILabel *label = (UILabel *)[self.view viewWithTag:((j+1) * 10 + (i+1))];
                             [label setAlpha:0.0f];
                             [label setText:[cryptograms objectAtIndex:i * 12 + j]];
                             [label setAlpha:1.0f];
                         }
                     }
                 } completion:^(BOOL finished) {
                     if (finished) {
                         ...
                     }
                 }];
answered on Stack Overflow Nov 13, 2012 by abu.marcose

User contributions licensed under CC BY-SA 3.0