2017-05-21 69 views
1

在Objective-C,我们可以初始化CADisplayLink与代理模式打破有力的参考:如何与目标和CADisplayLink实例之间的弱引用设置CADisplayLink斯威夫特

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

然后,就无效的DisplayLink在dealloc

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

但是,NSProxy似乎不能在斯威夫特继承:https://bugs.swift.org/browse/SR-1715

我试着写这样的:

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

它没有工作。

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

回答

3

一个更好的办法可能是显示链接 viewWill/DidDisappear无效,又见

有用的信息。

如果这不是一个选项:让代理对象从NSObject 而不是NSProxy继承。一个Objective-C溶液是例如 这里给出

并且可以很容易地转换为夫特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:))) 

不起作用,因为它解开weakSelfCADisplayLink 被初始化并传递一个强有力的参考self为目标。

0

这个代理类应该工作。不要忘记在dealloc之前失效。

import UIKit 

class CADisplayLinkProxy { 

    var displaylink: CADisplayLink? 
    var handle: (() -> Void)? 

    init(handle: (() -> Void)?) { 
     self.handle = handle 
     displaylink = CADisplayLink(target: self, selector: #selector(updateHandle)) 
     displaylink?.add(to: RunLoop.current, forMode: .commonModes) 
    } 

    @objc func updateHandle() { 
     handle?() 
    } 

    func invalidate() { 
     displaylink?.remove(from: RunLoop.current, forMode: .commonModes) 
     displaylink?.invalidate() 
     displaylink = nil 
    } 
} 

用法:

var displaylinkProxy = CADisplayLinkProxy(handle: { [weak self] in 
        self?.updateTime() 
       })