UIView, CMDeviceMotionHandler : unowned may only be applied to class and class-bound protocol types

只谈情不闲聊 提交于 2020-01-06 23:52:06

问题


I'm creating a UIView that listens to CMDeviceMotion Events:

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
    }
}

I'd like to declare my CMDeviceMotionHandler closure as a member variable however I get the error:

'unowned' may only be applied to class and class-bound protocol types, not 'MyView -> () -> MyView'

MyView is a UIView which in turn is a class so I don't get why it's complaining that unowned can not be applied.

I've searched for other questions with the same issue but most of them dealt with lazily computed variables. How do I resolve this error for my scenario?


回答1:


The line of code you're on is actually run during the init function. self is not available until after all stored properties are initialized. You're in the middle of the process.

The error message is quite confusing and useless, because self in the context of property initializers is not an instance of a MyView, but a tricky meta-type: a class-member function that is unbound to its instance, but becomes bound and usable once the instance is passed in as the first argument. It's to do with member functions being implemented in Swift with currying, and is rather academic unless you love type calculus.

You have two options:

  1. Declare it indeed as lazy var instead of let, so the code is not run during init but in fact at first use.

  2. Declare it without initialization as an Optional. Depending on your design constraints this is either cumbersome or elegant. No way to know. Anyway, before it is needed, initialize it to a non-nil value. An easy place to do this, if this UIView is used strictly within Storyboard, is to initialize it within awakeFromNib().



来源:https://stackoverflow.com/questions/39560860/uiview-cmdevicemotionhandler-unowned-may-only-be-applied-to-class-and-class-b

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!