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

men*_*awi 0 closures swift

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
    }
}
Run Code Online (Sandbox Code Playgroud)

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?

Bas*_*Zen 5

您所在的代码行实际上是在init函数运行期间运行的。初始化所有存储的属性self之前该属性不可用。您处于流程的中间。

该错误消息是相当混乱和无用,因为self在属性初始化的上下文是不是一个实例MyView,但是一个棘手的间位型:一类成员函数,它是未结合到它的实例,但变得结合并可用一次实例作为第一个参数传入。这与在Swing中使用currying实现的成员函数有关,除非您喜欢类型演算,否则它是学术性的。

您有两种选择:

  1. 确实声明它为,lazy var而不是声明它let,因此代码不是在运行时init而是在首次使用时运行的。

  2. 声明它而不初始化为Optional。根据您的设计约束,这既麻烦又优雅。没办法知道。无论如何,在需要它之前,请将其初始化为非nil值。如果UIView严格在Storyboard中使用此代码,那么一个简单的方法是在中将其初始化awakeFromNib()