【问题标题】:UIView, CMDeviceMotionHandler : unowned may only be applied to class and class-bound protocol typesUIView, CMDeviceMotionHandler : unowned 只能应用于类和类绑定协议类型
【发布时间】:2016-09-19 02:44:00
【问题描述】:

我正在创建一个监听 CMDeviceMotion 事件的 UIView:

class MyView: UIView{


    private var motionManager = CMMotionManager()
    let motionQueue = NSOperationQueue()


    override func awakeFromNib() {
        self.setupView()
    }

    func setupView(){
        self.motionManager.deviceMotionUpdateInterval = 0.5
        self.motionManager.startDeviceMotionUpdatesUsingReferenceFrame(.XArbitraryZVertical, toQueue: self.motionQueue, withHandler: self.motionHandler)
    }

    // MARK: - CMDeviceMotionHandler

    let motionHandler : CMDeviceMotionHandler = {
        [unowned self] (motion,error) in
    }
}

我想将我的 CMDeviceMotionHandler 闭包声明为成员变量,但我得到了错误:

'unowned' 只能应用于类和类绑定协议类型, 不是'我的视图->()->我的视图'

MyViewUIView,而 UIView 又是一个类,所以我不明白为什么它抱怨不能应用 unowned

我已经搜索了具有相同问题的其他问题,但其中大多数都涉及延迟计算的变量。如何为我的方案解决此错误?

【问题讨论】:

    标签: swift closures


    【解决方案1】:

    您所在的代码行实际上是在 init 函数期间运行的。 self 直到所有存储的属性都被初始化后才可用。你正处于这个过程的中间。

    错误信息相当混乱和无用,因为在属性初始化器上下文中的self 不是MyView实例,而是一个棘手的元类型:类成员未绑定到其实例的函数,但一旦实例作为第一个参数传入,它就会变得绑定和可用。这与在 Swift 中使用 currying 实现的成员函数有关,除非你喜欢类型演算,否则它相当学术。

    你有两个选择:

    1. 确实将其声明为lazy var 而不是let,因此代码init 期间运行,但实际上在第一次使用时运行。

    2. 在不初始化的情况下将其声明为 Optional。根据您的设计限制,这不是繁琐就是优雅。没办法知道。无论如何,在需要之前,将其初始化为非零值。如果在 Storyboard 中严格使用此 UIView,则执行此操作的一个简单方法是在 awakeFromNib() 中对其进行初始化。

    【讨论】:

    • 感谢您提供如此丰富的答案。我采用了第二种方法,效果很好:)
    猜你喜欢
    • 2018-02-07
    • 2016-10-26
    • 1970-01-01
    • 2018-05-21
    • 2019-11-23
    • 2016-02-01
    • 2020-04-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多