Swift 自定义动画中 CADisplayLink 的正确处理清理等

作者:编程家 分类: swift 时间:2025-12-11

使用 CADisplayLink 主要是为了在每个屏幕刷新周期调用指定的方法,以实现流畅的动画效果。然而,在使用 CADisplayLink 进行自定义动画时,我们需要正确处理和清理 CADisplayLink,以避免内存泄漏和其他潜在问题。

CADisplayLink 的创建和启动

在开始使用 CADisplayLink 之前,我们需要创建一个 CADisplayLink 对象,并将它与指定的方法进行关联。通常,我们会在初始化方法或 viewDidLoad() 中进行这些操作。

swift

class ViewController: UIViewController {

var displayLink: CADisplayLink?

override func viewDidLoad() {

super.viewDidLoad()

displayLink = CADisplayLink(target: self, selector: #selector(update))

displayLink?.add(to: .main, forMode: .default)

}

@objc func update() {

// 在这里更新动画

}

}

在上面的例子中,我们在 viewDidLoad() 方法中创建了一个 CADisplayLink 对象,并将其与 update() 方法进行关联。然后,我们使用 add(to:forMode:) 方法将 CADisplayLink 添加到主运行循环中。

动画更新方法

在使用 CADisplayLink 进行自定义动画时,我们需要在 update() 方法中更新动画的状态。这个方法会在每个屏幕刷新周期调用一次。

swift

@objc func update() {

// 更新动画状态

// ...

// 判断是否动画结束,结束后需要将 CADisplayLink 停止并清理

if animationFinished {

displayLink?.invalidate()

displayLink = nil

}

}

在 update() 方法中,我们可以更新动画的状态,例如更新位置、改变透明度等。在动画结束时,我们需要调用 invalidate() 方法停止 CADisplayLink,并将其设置为 nil,以避免内存泄漏。

动画开始和结束

通常情况下,我们会在开始动画时启动 CADisplayLink,并在动画结束时停止并清理 CADisplayLink。

swift

func startAnimation() {

displayLink?.isPaused = false

}

func stopAnimation() {

displayLink?.isPaused = true

displayLink?.invalidate()

displayLink = nil

}

在 startAnimation() 方法中,我们将 CADisplayLink 的 isPaused 属性设置为 false,以启动动画。而在 stopAnimation() 方法中,我们将 isPaused 属性设置为 true,以停止动画,并使用 invalidate() 方法停止 CADisplayLink,最后将其设置为 nil。

内存管理和循环引用

在使用 CADisplayLink 进行自定义动画时,我们需要注意内存管理和循环引用的问题。如果我们在控制器中使用 CADisplayLink,而且控制器持有了 CADisplayLink,可能会导致循环引用,从而造成内存泄漏。

为了避免这个问题,我们可以使用 weak self 或 unowned self 来避免循环引用。

swift

displayLink = CADisplayLink(target: self, selector: #selector(update))

displayLink?.add(to: .main, forMode: .default)

// 使用 weak self

displayLink?.add(to: .main, forMode: .default, withWeakTarget: self, selector: #selector(update))

// 使用 unowned self

displayLink?.add(to: .main, forMode: .default, withUnownedTarget: self, selector: #selector(update))

在上面的示例中,我们可以使用 add(to:forMode:withWeakTarget:selector:) 方法或 add(to:forMode:withUnownedTarget:selector:) 方法来避免循环引用。

使用 CADisplayLink 进行自定义动画时,我们需要正确处理和清理 CADisplayLink,以避免内存泄漏和其他潜在问题。在创建和启动 CADisplayLink 时,我们需要将其与指定的方法进行关联,并将其添加到主运行循环中。在动画更新方法中,我们可以更新动画的状态,并在动画结束时停止并清理 CADisplayLink。另外,我们还需要注意内存管理和循环引用的问题,使用 weak self 或 unowned self 来避免循环引用。

通过正确处理和清理 CADisplayLink,我们可以更好地实现自定义动画,并提供更好的用户体验。

以上是关于使用 CADisplayLink 进行自定义动画的一些注意事项和示例代码。希望对你有所帮助!