在阅读了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;
});
}
];
以下是在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
}
}
})
答案 0 :(得分:12)
通过执行CMAccelerometerData()
和NSError()
,您实际上正在调用这些类的初始值设定项。你只需要使用他们的类型。但是,因为在objective-C中,指针可以是nil,当你将类型转换为Swift时,你需要使用选项。惯例是使用Implicitly Unwrapped Optionals。此外,您将匿名闭包的参数与in
分开,而不是附加的大括号:
self.motionManager.startAccelerometerUpdatesToQueue(NSOperationQueue(), withHandler: {
(data: CMAccelerometerData!, error: NSError!) in
// internal implementation
})
此外,因为可以从参数类型推断出类型,所以您甚至不必指定参数的类型:
self.motionManager.startAccelerometerUpdatesToQueue(NSOperationQueue(), withHandler: {
(data, error) in
// internal implementation
})
此外,如果块是方法/函数调用的最后一个参数,则可以在括号外定义:
self.motionManager.startAccelerometerUpdatesToQueue(NSOperationQueue()) {
(data, error) in
// internal implementation
}
这样,关闭后你不需要关闭)
。
使用您的内部实现创建最终版本:
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
}
}