私のアプリの状況:
現在、動的な画像を表示するアプリを使用しています。そして、現在の画像をキャプチャしてディスクに保存したいと思います。
私の目標:
私はアニメーション化された視覚効果に取り組んでいます: 上に画像ビューを追加し、元のフレームから CGRecrZero にアニメーション化します。最後に、アニメーションが完了したら、この画像ビューを Vie 階層から削除します。
今の問題:
初めてアクションをトリガーすると、うまくいくようです。しかし、2 回目にトリガーすると、画像ビューはアニメーション化されず、すべてのサブビューの上にとどまります。
ビューコントローラーのコード(ARC あり):
まず、これはスナップショットをトリガーする IBAction です。
- (IBAction)actionSaveSnapshot:(id)sender
{
... // Save the image file. This works everytime.
NSThread *tempThread = [[NSThread alloc] initWithTarget:self
selector:@selector(threadSimulateScreenCapture:)
object:nil];
if (tempThread)
{
[tempThread start];
tempThread = nil; // Simply release it
}
}
そして、ここにスレッドがあります:
- (void)threadSimulateScreenCapture:(id)arg
{@autoreleasepool {
NSImageView __strong *subImageView;
subImageView = [[NSImageView alloc] init];
NSRect subRect = [_imageView frame]; // the dynamic image view which I want to snapshot with
const CGFloat animationTime = 0.4;
[subImageView setWantsLayer:YES];
[subImageView setImageScaling:NSImageScaleAxesIndependently];
[subImageView setImage:[_imageView image]];
dispatch_async(dispatch_get_main_queue(), ^{
[CATransaction begin];
[self.view addSubview:subImageView];
[subImageView setFrame:subRect];
[subImageView setNeedsDisplay:YES];
[CATransaction commit];
});
[NSThread sleepForTimeInterval:0.01];
dispatch_async(dispatch_get_main_queue(), ^{
[CATransaction begin];
[CATransaction setAnimationDuration:animationTime];
[subImageView.layer setFrame:CGRectZero];
[CATransaction commit];
});
[NSThread sleepForTimeInterval:(NSTimeInterval)animationTime]; // wait for end of animation
dispatch_async(dispatch_get_main_queue(), ^{
[subImageView removeFromSuperview];
});
NSLog(@"SubView Count: %@\n%@", self.view.subviews, subImageView); // MARK. described below
subImageView = nil; // release the image
}} // ENDS: thread and aotureleasepool
プログラムが「MARK」行まで実行されてサブビュー配列が出力されるたびに、それがsubImageView
スーパービューから削除されていないことは明らかです。そして、スレッドが終了するたびに、「コミットされていない CATransaction を持つ削除されたスレッド ....」が発生しました。
私は何を間違えましたか?