>>> Image loading would be the first thing I would move into a background
>>> thread. Can you use GCD? It’s a perfect fit for such producer/consumer
>>> tasks.
>>
>> Please explain "GCD".
GCD would be ideal, and less complicated than the creating a thread most
likely.It's even a quick read. Blocks (closures) however took me a little while
to wrap my brain around, having never used them previously.
> Good question. One problem is that I have not understood a fundamental
> property of Core Animation.
> I have always assumed that the animation, once I have set it up, is done by
> the OS / Core Animation in the background, i.e., in a separate thread.
> Is that correct?
No.**
> If yes, then wouldn't that mean that moving my image loading into a separate
> thread would *not* help at all?
> If no, then exactly when / where is the animation performed?
Anything you can see on screen happens on your apps main thread.**
Anything that blocks the main thread, even a little, or only in rare
situations, will cause animation judder or other UI issues (spinning beach ball
is the gold standard).
So, yes, it's not the CPU usage or I/O activity that is likely the cause of
your animation judder it's just when the main thread is blocked, it's blocked.
CATransaction's begin and commit schedules it to run on the main thread, but it
can't update the animation when processing user events. One potential might be
to move all processing out of animateOneFrame:
** in the context of most application level programming tasks, but I suspect my
succinct answers here are technically incomplete.
// .h
BOOL isConstructingNextFrameLayer;
@property (assign) BOOL isConstructingNextFrameLayer;
@property (retain) CALayer *nextFrameLayer;
// .m
@synthesize isConstructingNextFrameLayer;
@synthesize nextFrameLayer;
- (void) animateOneFrame
{
if ( !self.isConstructingNextFrameLayer ) /* setup for next layer swap is
needed */
{
// GCD is built into libsystem, so you wont need to add any frameworks to
your project
// or create a thread if you prefer or can't use GCD
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,
0), ^{
self.isConstructingNextFrameLayer = YES;
// load new image from disk
NSURL * url = [NSURL fileURLWithPath: [self absolutePathFor: filename_]
isDirectory: NO];
...
CGImageSourceRef sourceRef = CGImageSourceCreateWithURL( (CFURLRef) url,
NULL );
CFDictionaryRef fileProps = CGImageSourceCopyPropertiesAtIndex(
sourceRef, 0, NULL );
... [check whether image is eligible for display; if not, return]
CGImageRef imageRef = CGImageSourceCreateImageAtIndex( sourceRef, 0, NULL
);
CFRelease(sourceRef);
...
// do garbage collection a bit later, to prevent judder
#warning this looks unneccessary at first glance
[NSTimer scheduledTimerWithTimeInterval: 2.3 target: self selector:
@selector(doGarbageCollection:) userInfo: nil repeats: NO];
self.nextFrameLayer = [self makeImageLayer: imageRef fromSize: startsize
toSize: endsize withOrientation: img_orientation];
});
}
if ( /* time for layer swapping is not up yet */ ) {
return;
}
[CATransaction begin];
[CATransaction setValue: [NSNumber numberWithFloat: fading_duration] forKey:
kCATransactionAnimationDuration ];
[mainLayer_ replaceSublayer:currentLayer_ with:self.nextFrameLayer];
currentLayer_ = newlayer;
[CATransaction commit];
self.nextFrameLayer = nil;
self.isConstructingNextFrameLayer = NO;
}
_______________________________________________
Cocoa-dev mailing list ([email protected])
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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com
This email sent to [email protected]