如何使用目标和 CADisplayLink 实例之间的弱引用在 Swift 中设置 CADisplayLink [英] How to set CADisplayLink in Swift with weak reference between target and CADisplayLink instance

查看:42
本文介绍了如何使用目标和 CADisplayLink 实例之间的弱引用在 Swift 中设置 CADisplayLink的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在 Objective-C 中,我们可以使用代理模式初始化 CADisplayLink 来打破强引用:

In Objective-C, we can init CADisplayLink with Proxy Pattern to break strong reference:

WeakProxy *weakProxy = [WeakProxy weakProxyForObject:self];
self.displayLink = [CADisplayLink displayLinkWithTarget:weakProxy selector:@selector(displayDidRefresh:)];

然后,只需使 dealloc 中的 displayLink 无效:

Then, just invalidate the displayLink in dealloc:

- (void)dealloc
{
    [_displayLink invalidate];
}

然而,NSProxy 似乎无法在 Swift 中继承:https://bugs.swift.org/browse/SR-1715

However, NSProxy seems can't be inherited in Swift: https://bugs.swift.org/browse/SR-1715

我试着这样写:

weak var weakSelf = self    
displayLink = CADisplayLink(target: weakSelf!, selector: #selector(displayDidRefresh(dpLink:)))

没用.

我想知道是否有任何方法可以像在 Objective-C 中那样实现这一点.

I would like to know if there is any way to achieve this like in Objective-C.

推荐答案

更好的方法可能是使显示链接无效viewWill/DidDisappear,另见

An better approach might be to invalidate the display link in viewWill/DidDisappear, see also

有用的信息.

如果这不是一个选项: 使代理对象继承自 NSObject而不是 NSProxy.例如,Objective-C 解决方案是这里给出

If that is not an option: Make the proxy object inherit from NSObject instead of NSProxy. An Objective-C solution is for example given here

并且可以轻松转换为 Swift 3:

and that can easily be translated to Swift 3:

class JAWeakProxy: NSObject {
    weak var target: NSObjectProtocol?

    init(target: NSObjectProtocol) {
        self.target = target
        super.init()
    }

    override func responds(to aSelector: Selector!) -> Bool {
        return (target?.responds(to: aSelector) ?? false) || super.responds(to: aSelector)
    }

    override func forwardingTarget(for aSelector: Selector!) -> Any? {
        return target
    }
}

然后可以用作

displayLink = CADisplayLink(target: JAWeakProxy(target: self),
                            selector: #selector(didRefresh(dpLink:)))

你的方法

weak var weakSelf = self    
displayLink = CADisplayLink(target: weakSelf!, selector: #selector(displayDidRefresh(dpLink:)))

不起作用,因为它在 CADisplayLink 时解开 weakSelf被初始化并传递一个对 self 的强引用作为目标.

does not work because it unwraps weakSelf when the CADisplayLink is initialized and passes a strong reference to self as the target.

这篇关于如何使用目标和 CADisplayLink 实例之间的弱引用在 Swift 中设置 CADisplayLink的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆