在Objective中,我们可以使用代理模式插入CADisplayLink以打破强引用:
WeakProxy *weakProxy = [WeakProxy weakProxyForObject:self];
self.displayLink = [CADisplayLink displayLinkWithTarget:weakProxy selector:@selector(displayDidRefresh:)];然后,只需使displayLink在dealloc中失效。
- (void)dealloc
{
[_displayLink invalidate];
}然而,NSProxy似乎不能在Swift:https://bugs.swift.org/browse/SR-1715中被继承
我试着这样写:
weak var weakSelf = self
displayLink = CADisplayLink(target: weakSelf!, selector: #selector(displayDidRefresh(dpLink:)))它没有起作用。
我想知道在目标C中是否有实现这一目标的方法。
发布于 2020-06-05 16:00:11
另一种解决方案是,该解决方案将代理/ objc运行时隐藏在其外部API中。只要DisplayLink被变量引用,它就能存活多久。一旦变量超出作用域或设置为零,CADisplayLink将失效,以便也可以对目标进行删除。
import Foundation
import UIKit
/// DisplayLink provides a block based interface for CADisplayLink.
/// The CADisplayLink is invalidated upon DisplayLink deinit.
///
/// Usage:
/// ```
/// let displayLink = DisplayLink { caDisplayLink in print("Next frame scheduled \(caDisplayLink.targetTimestamp)") }
/// ```
///
/// Note: Keep a reference to the DisplayLink.
final class DisplayLink {
let displayLink: CADisplayLink
init(runloop: RunLoop? = .main, prepareNextFrame: @escaping (CADisplayLink) -> ()) {
displayLink = CADisplayLink(
target: DisplayLinkTarget(prepareNextFrame),
selector: #selector(DisplayLinkTarget.prepareNextFrame))
if let runloop = runloop {
displayLink.add(to: runloop, forMode: .default)
}
}
deinit {
displayLink.invalidate()
}
}
private class DisplayLinkTarget {
let callback: (CADisplayLink) -> ()
init(_ callback: @escaping (CADisplayLink) -> ()) {
self.callback = callback
}
@objc func prepareNextFrame(displaylink: CADisplayLink) {
callback(displaylink)
}
}https://stackoverflow.com/questions/44096793
复制相似问题