CALayerにアニメーションを追加して、NSOperationからレイヤの位置を確認する方法

コード

TestViewをwindowに追加して、コンパイルし、画面をクリックするだけ。

TestViewヘッダファイル

@interface TestView : UIView {
  NSOperationQueue *operationQueue_;
}
@property (nonatomic, retain) NSOperationQueue *operationQueue;

@end

TestViewの定義

//
//  TestView.m
//  AnimTest
//
//  Created by nobuyuki on 10/08/17.
//  Copyright 2010 __MyCompanyName__. All rights reserved.
//

#import "TestView.h"
#import  <QuartzCore/QuartzCore.h>


@implementation TestView
@synthesize operationQueue = operationQueue_;

#pragma mark -
#pragma mark test 

int cnt;

- (id)initWithFrame:(CGRect)frame {
    if ((self = [super initWithFrame:frame])) {
    cnt = 10;
    CGFloat layerWidth = self.bounds.size.width / cnt;
    CGFloat layerHeight = 10;
    int i = 0;
    for (i = 0; i < cnt; i++) {
      CALayer *layer = [CALayer layer];
      layer.bounds = CGRectMake(0, 0, layerWidth / 2, layerHeight);
      layer.position = CGPointMake(layerWidth * i + layerWidth / 2, layerHeight / 2);
      layer.backgroundColor = [UIColor colorWithHue:1.0f / cnt * i saturation:1.0f brightness:1.0f alpha:1.0f].CGColor;
      [self.layer addSublayer:layer];
    }
    self.operationQueue = [[[NSOperationQueue alloc] init] autorelease];
    /*
    CheckOperation *op = [[CheckOperation alloc] init];
    op.layer = [self.layer.sublayers objectAtIndex:0];
    [self.operationQueue addOperation:op];
    */
    CALayer* checkLayer = [self.layer.sublayers objectAtIndex:0];
    [self.operationQueue addOperationWithBlock:^{
      for ( ; ; ) {
        id pool = [[NSAutoreleasePool alloc] init]; // (追記)
        [NSThread sleepForTimeInterval:0.01f];
        [CATransaction begin];
        [CATransaction setDisableActions:YES];
        NSLog(@"test %x %@", checkLayer, [NSValue valueWithCGPoint: ((CALayer *)checkLayer.presentationLayer).position]);
        [CATransaction commit];
        [pool release];
      }
    }];
    
  }
    return self;
}


- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
  for (CALayer *layer in self.layer.sublayers) {
    CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:@"position"];
    anim.duration = 1.0f;
    anim.fromValue = [NSValue valueWithCGPoint:layer.position];
    anim.toValue = [NSValue valueWithCGPoint:CGPointMake(layer.position.x, self.bounds.size.height)];
    anim.autoreverses = YES;
    anim.repeatCount = UINT_MAX;
    [layer addAnimation:anim forKey:@"move"];
  }
}

/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
    // Drawing code
}
*/

- (void)dealloc {
  self.operationQueue = nil;
  [super dealloc];
}

@end

なぜかわからないが、別スレッドからでもCATransactionとpresentationLayerを使えば値の取得ができることがわかった。