PDA

View Full Version : asynchronous coding




beardedpig
Dec 27, 2008, 08:36 AM
Hi, I have a on off button which I want to trigger some animation in a view.

The problem I am having is that I cannot see how to have the animation loop run asynchronously?

At the moment it takes over the application and I cannot get it to stop the animation.

Is there a special class for this kind of thing? I am not using the BeginAnimation block etc as at present the animation is a simple cycle through multiple images.

Thanks



beardedpig
Dec 27, 2008, 11:20 AM
OK I found this link which tells me about NSOperation and NSOperationQueue

http://www.cimgf.com/2008/02/16/cocoa-tutorial-nsoperation-and-nsoperationqueue/

I have tried to elbow this into my app as follows but although the app does not crash it does not repsond to the NSOperation bit?

from the app delegate .h


#import <UIKit/UIKit.h>

@class RotateViewController;

BOOL animateNow;
NSOperationQueue *queue;

@interface RotateAppDelegate : NSObject <UIApplicationDelegate> {
UIWindow *window;
RotateViewController *viewController;
UIImageView *viewP;
}


from RotateViewCotroller.h

this code runs and actions each line but nothing happens with it?


-(IBAction) animateChanged: (id) sender
{
if ( animate.isOn == YES )
{
animateNow=YES;

AnimationHandler *ah = [[AnimationHandler alloc] init];

[queue addOperation: ah];

[ah release];
}
else
animateNow= NO;

}


from AnimationHandler.m


-(void)main
{

appDelegate = (RotateAppDelegate *) [[UIApplication sharedApplication] delegate];

UIImage *img;

int imageIndex = 0;

while (animateNow)
{
imageIndex++;

img = [UIImage imageNamed: [[NSString alloc] initWithFormat: @"myPics%d.png", imageIndex]];

[appDelegate.viewP setImage: img];

if (imageIndex == 1)
imageIndex = 25;
}
}


when the user clicks the UISwitch the animateNow is set to YES or NO respectivley

If YES the AnimationHandler is created and pushed onto the NSOperationQueue

the loop shoould run while animateNow is YES and cycle through the images.

If the user click the animate UISwitch to NO then this loop should stop and the AnimationHandler should fall off the queue.

have i misunderstood the concept?

thanks

dejo
Dec 27, 2008, 03:16 PM
What about spawning a thread instead?

beardedpig
Dec 28, 2008, 11:02 AM
ooo nice ;)

did a search on spawning threads and got this:

http://developer.apple.com/DOCUMENTATION/Cocoa/Conceptual/Multithreading/CreatingThreads/chapter_4_section_3.html

reading now.....

ta
:)

beardedpig
Dec 28, 2008, 12:23 PM
Excellent, it looks like the spawning a thread is the way to go.

Now if the UISwitch is tapped ON the thread starts and if it is tapped NO the thread stops.

However I ran the method that gets called with an NSLog statement which allowed me to see that the thread was running and stopping when required, but now I have changed to code to update a UIImageView it steps over the code as though it is executing it but nothing is updated on the screen.

If I run it in debug I can see the loop running correctly so I know the lines of code are running but in real tie nothing?

this is my thread method:


-(void) animateHandler
{
UIImage *img;

while (animateNow)
{
img = [UIImage imageNamed: [[NSString alloc] initWithFormat: @"myPic%d.png", imageIndex]];

[viewPort setImage: img];

imageIndex++;

if (imageIndex == 25)
imageIndex = 1;
}
}


Also as an after thought should this code bloc have an autoreleasepool to deal with the NSString allocation?

Thanks

beardedpig
Dec 28, 2008, 01:08 PM
I have found if I put this loop in the main body of my app just to test the line [viewPort setImage: img]; gets run but nothing happens to the sreen?

but if I use the same line in the touchesBegan method it fires with every tap.

I tried the setNeedsDisplay also in case a forced sreen refresh was needed but that does not work either.

beardedpig
Dec 28, 2008, 03:30 PM
And the latest attempt is to use animations in the UIImageView itself:


if (animateNow)
{
[viewPort setAnimationImages: animations];
[viewPort setAnimationDuration: 1.2];
[viewPort startAnimating];
}
else
[viewPort stopAnimating];


animations is an NSMutableArray set with 25 UIImage .png files that is setup in the viewDidLoad method.

viewPort already has an image on it but if the user taps the animate UISwitch to ON then the code above runs

again the debugging shows this code is running but nothing happens on the screen?