如何在Swift中正确地将块处理程序传递给此函数?

Nea*_*int 3 closures ios objective-c-blocks swift

在阅读了Swift Closures并尝试使用相同的语法将匿名函数传递给处理程序之后,我无法进行编译.如何在Swift中正确地重新创建以下正常运行的目标c代码?

这是我试图在swift中重新创建的目标c代码

 [self.motionManager
     startAccelerometerUpdatesToQueue:[[NSOperationQueue alloc] init]
     withHandler:^(CMAccelerometerData *data, NSError *error)
     {

         dispatch_async(dispatch_get_main_queue(),
                        ^{

                            float xx = data.acceleration.x;
                            float yy = -data.acceleration.y;
                            float angle = atan2(yy, xx);

                            self.dropitBehavior.gravity.angle = angle;
                         });
     }
 ];
Run Code Online (Sandbox Code Playgroud)

以下是在swift中重新创建代码的失败尝试:

self.motionManager.startAccelerometerUpdatesToQueue(NSOperationQueue(), withHandler: {
            (data: CMAccelerometerData(), error: NSError()) -> Void = {
                dispatch_async(dispatch_get_main_queue()) {
                    var xx = data.acceleration.x
                    var yy = -data.acceleration.y
                    var angle = atan2(yy, xx)

                    self.dropitBehavior.gravity.angle = angle
                }
            }
  })

self.motionManager.startAccelerometerUpdatesToQueue(NSOperationQueue(), withHandler: {
            (data: CMAccelerometerData(), error: NSError()) {
                dispatch_async(dispatch_get_main_queue()) {
                    var xx = data.acceleration.x
                    var yy = -data.acceleration.y
                    var angle = atan2(yy, xx)

                    self.dropitBehavior.gravity.angle = angle
                }
            }
 })
Run Code Online (Sandbox Code Playgroud)

dre*_*wag 12

通过这样做CMAccelerometerData(),NSError()您实际上正在调用这些类的初始化器.你只需要使用他们的类型.但是,因为在objective-C中,指针可以是nil,当你将类型转换为Swift时,你需要使用选项.惯例是使用Implicitly Unwrapped Optionals.此外,您将匿名闭包的参数与in其他大括号分开:

self.motionManager.startAccelerometerUpdatesToQueue(NSOperationQueue(), withHandler: {
    (data: CMAccelerometerData!, error: NSError!) in
    // internal implementation
})
Run Code Online (Sandbox Code Playgroud)

此外,因为可以从参数类型推断出类型,所以您甚至不必指定参数的类型:

self.motionManager.startAccelerometerUpdatesToQueue(NSOperationQueue(), withHandler: {
    (data, error) in
    // internal implementation
})
Run Code Online (Sandbox Code Playgroud)

此外,如果块是方法/函数调用的最后一个参数,则可以在括号外定义它:

self.motionManager.startAccelerometerUpdatesToQueue(NSOperationQueue()) {
    (data, error) in
    // internal implementation
}
Run Code Online (Sandbox Code Playgroud)

这样你就不需要在关闭)后关闭.

这将创建内部实现的最终版本:

self.motionManager.startAccelerometerUpdatesToQueue(NSOperationQueue()) {
    (data, error) in
    dispatch_async(dispatch_get_main_queue()) {
        var xx = data.acceleration.x
        var yy = -data.acceleration.y
        var angle = atan2(yy, xx)

        self.dropitBehavior.gravity.angle = angle
    }
}
Run Code Online (Sandbox Code Playgroud)