Use proxy object to prevent strong reference cycle
- Closes #55 - Closes #12
This commit is contained in:
parent
75220e571c
commit
367144ac1f
|
@ -2,11 +2,26 @@ import UIKit
|
||||||
|
|
||||||
/// A subclass of `UIImageView` that can be animated using an image name string or raw data.
|
/// A subclass of `UIImageView` that can be animated using an image name string or raw data.
|
||||||
public class AnimatableImageView: UIImageView {
|
public class AnimatableImageView: UIImageView {
|
||||||
|
/// Proxy object for preventing a reference cycle between the CADisplayLink and AnimatableImageView.
|
||||||
|
/// Source: http://merowing.info/2015/11/the-beauty-of-imperfection/
|
||||||
|
class TargetProxy {
|
||||||
|
private weak var target: AnimatableImageView?
|
||||||
|
|
||||||
|
init(target: AnimatableImageView) {
|
||||||
|
self.target = target
|
||||||
|
}
|
||||||
|
|
||||||
|
@objc func onScreenUpdate() {
|
||||||
|
target?.updateFrame()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// An `Animator` instance that holds the frames of a specific image in memory.
|
/// An `Animator` instance that holds the frames of a specific image in memory.
|
||||||
var animator: Animator?
|
var animator: Animator?
|
||||||
|
|
||||||
/// A display link that keeps calling the `updateFrame` method on every screen refresh.
|
/// A display link that keeps calling the `updateFrame` method on every screen refresh.
|
||||||
lazy var displayLink: CADisplayLink = {
|
lazy var displayLink: CADisplayLink = {
|
||||||
let display = CADisplayLink(target: self, selector: #selector(updateFrame))
|
let display = CADisplayLink(target: TargetProxy(target: self), selector: #selector(TargetProxy.onScreenUpdate))
|
||||||
display.paused = true
|
display.paused = true
|
||||||
return display
|
return display
|
||||||
}()
|
}()
|
||||||
|
@ -93,8 +108,9 @@ public class AnimatableImageView: UIImageView {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Invalidate the displayLink so it releases this object.
|
/// Invalidate the displayLink so it releases its target.
|
||||||
deinit {
|
deinit {
|
||||||
|
// invalidate will also remove the link from all run loops
|
||||||
displayLink.invalidate()
|
displayLink.invalidate()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,5 +118,5 @@ public class AnimatableImageView: UIImageView {
|
||||||
func attachDisplayLink() {
|
func attachDisplayLink() {
|
||||||
displayLink.addToRunLoop(.mainRunLoop(), forMode: NSRunLoopCommonModes)
|
displayLink.addToRunLoop(.mainRunLoop(), forMode: NSRunLoopCommonModes)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue