UIView,CMDeviceMotionHandler:unowned只能应用于类和类绑定协议类型

时间:2016-09-18 17:54:12

标签: swift closures

我正在创建一个侦听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闭包声明为成员变量但是我收到了错误:

  

'无主'可能只适用于类和类绑定协议类型,   不是' MyView - > () - > MyView的'

MyView是一个UIView,而这又是一个课程,所以我不知道它为什么抱怨unowned无法应用。

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

1 个答案:

答案 0 :(得分:4)

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

错误消息非常混乱且无用,因为属性初始化程序的上下文中的self不是MyView实例,而是一个棘手的元类型:一个类成员函数,它未绑定到其实例,但在将实例作为第一个参数传入后变为绑定和可用。它与使用 currying 在Swift中实现的成员函数有关,除非你喜欢类型微积分,否则它更具学术性。

您有两种选择:

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

  2. 在没有初始化的情况下将其声明为Optional。根据您的设计限制,这既繁琐又优雅。没办法知道。无论如何,在需要之前,将其初始化为非零值。如果UIView严格用于故事板,则可以轻松地在awakeFromNib()内对其进行初始化。