Рассмотрим эту тривиальную синхронизацию,
var link:CADisplayLink?
var startTime:Double = 0.0
let animTime:Double = 0.2
let animMaxVal:CGFloat = 0.4
private func yourAnim()
{
if ( link != nil )
{
link!.paused = true
//A:
link!.removeFromRunLoop(
NSRunLoop.mainRunLoop(), forMode:NSDefaultRunLoopMode)
link = nil
}
link = CADisplayLink(target: self, selector: #selector(doorStep) )
startTime = CACurrentMediaTime()
link!.addToRunLoop(
NSRunLoop.currentRunLoop(), forMode:NSDefaultRunLoopMode)
}
func doorStep()
{
let elapsed = CACurrentMediaTime() - startTime
var ping = elapsed
if (elapsed > (animTime / 2.0)) {ping = animTime - elapsed}
let frac = ping / (animTime / 2.0)
yourAnimFunction(CGFloat(frac) * animMaxVal)
if (elapsed > animTime)
{
//B:
link!.paused = true
link!.removeFromRunLoop(
NSRunLoop.mainRunLoop(), forMode:NSDefaultRunLoopMode)
link = nil
yourAnimFunction(0.0)
}
}
func killAnimation()
{
// for example if the cell disappears or is reused
//C:
????!!!!
}
Кажется, что существуют различные проблемы.
At (A:), хотя link
не является нулевым, может быть невозможно удалить его из цикла запуска. (Например, кто-то может инициализировать его с помощью link = link:CADisplayLink()
- попробуйте его для сбоя.)
Во-вторых, в (B:) кажется, что это беспорядок... конечно, есть лучший (и более быстрый) способ, и что, если он равен нулю, даже если время просто истекло?
Наконец, в (C:), если вы хотите разбить анимацию... Я впал в депрессию и понятия не имею, что лучше.
И действительно, код в A: и B: должен быть тем же самым правом вызова, как и очищающий вызов.