gpt4 book ai didi

iphone - 停止在后台线程和运行循环中执行动画

转载 作者:塔克拉玛干 更新时间:2023-11-02 09:51:04 26 4
gpt4 key购买 nike

我在 UITAbleViewCell 中运行我的动画。每个单元格都有自己的动画,并且单元格是可重用的。我使用 [mView performSelectorInBackground:@selector(layoutSubview) withObject:nil];

在后台线程中,我启动了 runLoop 来执行这样的任务:

- (void)startAnimation 
{
NSRunLoop *mLoop = [NSRunLoop currentRunLoop];
self.animationTimer = [NSTimer scheduledTimerWithTimeInterval:animationInterval target:self selector:@selector(setNeedsDisplay) userInfo:nil repeats:YES];

mRunLoop = YES;
while (mRunLoop == YES && [mLoop runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.01]]);
}

并停止它:

- (void)stopAnimation 
{
if (![NSThread isMainThread]) {
[[NSThread currentThread] cancel];
}

mRunLoop = NO;
self.animationTimer = nil;
CFRunLoopStop(CFRunLoopGetCurrent());
}

当我快速滚动表格时遇到问题,因为在第一个单元格启动时我开始动画,所以第一个 runLoop 调用发生,它执行 setNeedDisplay 和它的所有方法。但是在完成第一个 runLoop 循环之前,单元格从 View 中消失并且已经可以重用了。所以我开始清除它,而循环仍在执行操作,在这里我遇到了类似的情况

message sent to deallocated instance

那么你能给我一些提示,告诉我应该如何正确地停止执行该线程中的操作吗?我的意思是,如果我想重新定义一个正在执行某些操作的对象,如何立即停止它们?

希望我提供了足够的信息。谢谢

更新:一点想法都没有?

最佳答案

我将采取完全不同的方式:

完全摆脱单元格的计时器和后台线程!

动画并不是 NSTimer 最适合的地方,拥有多个计时器也无济于事。

UITableView 有一个方法 visibleCells和一种方法 indexPathsForVisibleRows .我建议使用单个 CADisplayLink 适用于动画,因为它会用显示器的实际刷新率或其中的一小部分回调您 — 在您的 tableview-controller 和显示链接的回调中迭代可见细胞。

如果你想在辅助线程的运行循环上安排显示链接,请随意这样做,但我会先检查你是否可以在没有额外线程的情况下逃脱。

部分代码:

@interface AnimatedTableViewController ()

@property (strong, nonatomic) CADisplayLink *cellAnimator;
- (void)__cellAnimatorFired:(CADisplayLink *)animator;

@end

@implementation AnimatedTableViewController

@synthesize cellAnimator = cellAnimator_;

- (void)setCellAnimator:(CADisplayLink *)animator
{
if (animator == cellAnimator_)
return;

[cellAnimator_ invalidate];
cellAnimator_ = animator;

[cellAnimator_ addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSCommonRunLoopModes];
}

- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];

self.cellAnimator = [CADisplayLink displayLinkWithTarget:self selector:@selector(__cellAnimatorFired:)];
...
}

- (void)viewWillDisappear:(BOOL)animated
{
self.cellAnimator = nil;
...

[super viewWillDisappear:animated];
}

- (void)__cellAnimatorFired:(CADisplayLink *)animator
{
NSArray *visibleCells = [self.tableView visibleCells];
[visibleCells enumerateObjectsUsingBlock:^(UITableViewCell *cell, NSUInteger unused, BOOL *stop){
[cell setNeedsDisplay];
}];
}

...

@end

关于iphone - 停止在后台线程和运行循环中执行动画,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8559112/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com