I have a problem with updating a series of images to the existing UIImageView object which already has animating images. So I posted a question to iPhone Dev SDK forum.
Dealing with timer is kind of tricky. Especially when releasing a timer object before closing your application. I found that it's because a timer in the run loop may still point to the object even after you already released it depending on the schedule.
http://www.iphonedevsdk.com/forum/iphone-sdk-development/17000-how-change-animating-iamges-uiimageview.html#post77399Hi,
I am trying to reuse UIImageView object instead of creating a new one. I am doing so because I found that releasing a UIImageView having animation in the middle before closing the app makes the app crash.
It's because even after stopping a timer (stopAnimating), the timer in the run loop may still point to the already released object depending on the schedule. So I found that releasing a UIImageView which uses a timer object before closing the app is not quite safe. (Correct me if I'm wrong, but that's what I found)
This description from NSTimer class reference explains why:
"The run loop removes and releases the timer, either just before the invalidate method returns or
at some later point."
Anyways, how can I change animation images for the existing UIImageView which is currently animating?
stopAnimating itself is ok, but after that if I assign a new array of images, it crashes.
// This crashes the app
[self.imageView stopAnimating];
self.imageView.animationImages = newImageArr;
self.imageView.animationDuration = 0.75; // Duration in seconds
self.imageView.animationRepeatCount = 0; // zero loops forever
[self.imageView startAnimating];
-------------------------------------------------------------------------------------------------------It seems that there is no workaround to solve this problem. So I decided to do animation myself with NSTimer.
Here is a sample code.
// .h
NSTimer *animationTimer; // Used to animate bomb images
NSUInteger animationImageArrIndex;
NSMutableArray *animationImages; // Hold UIImages
// .m
- (void) viewDidLoad {
NSMutableArray *tmpMutableArr = [[NSMutableArray alloc] initWithCapacity:4];
self.animationImages = tmpMutableArr;
[tmpMutableArr release];
for( NSInteger i = 0; i < 4; i++ ) {
NSString *fileName = [[NSString alloc] initWithFormat:@"bomb%d.png", (i+1)];
UIImage *img = [UIImage imageNamed:fileName];
[fileName release];
[self.animationImages addObject:img];
[img release];
}
self.animationImageArrIndex = 0;
self.animationTimer = [NSTimer scheduledTimerWithTimeInterval:(0.75/4) target:self selector:@selector(animationTimerHandler) userInfo:nil repeats:YES];
}//end viewDidLoad
- (void) animationTimerHandler {
self.imageView.image = [self.animationImages objectAtIndex:self.animationImageArrIndex];
self.animationImageArrIndex ++;
if( self.animationImageArrIndex >= 4 )
self.animationImageArrIndex = 0;
}
- (void) updateAnimationImages:(NSMutableArray *)images {
if( [self.animationTimer isValid] == YES )
[self.animationTimer invalidate];
self.animationImages = images;
self.animationImageArrIndex = 0;
self.animationTimer = [NSTimer scheduledTimerWithTimeInterval:(0.75/4) target:self selector:@selector(animationTimerHandler) userInfo:nil repeats:YES];
}