>>> 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 (Cocoa-dev@lists.apple.com)

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 arch...@mail-archive.com

Reply via email to