Objective-C到Swift的完成处理程序

时间:2016-02-15 22:48:40

标签: ios objective-c swift objective-c-blocks

我目前正在重写一个从Objective-C到Swift的项目。大部分项目已完成,但我在翻译具有完成处理程序的方法时遇到问题。我已经查看了文档,但我仍然遇到问题。方法是:

- (void)start:(void ( ^ ) ( WTStartupConfiguration *configuration ))startupHandler 
completion:(void ( ^ ) ( BOOL isRunning , NSError *error ))completionHandler

在Objective-C中,我只想写为:

[self.architectView start:^(WTStartupConfiguration *configuration)
 { } completion:^(BOOL isRunning, NSError *error) {}}];

我无法很好地掌握Swift中的闭包语法。任何帮助将不胜感激!

3 个答案:

答案 0 :(得分:4)

你想要这样的功能:

func start(startupHandler:(configuration: WTStartupConfiguration)->(), completion:(isRunning:Bool, error:NSError?)->()) {

    let configuration = WTStartupConfiguration() // create your configuration

    startupHandler(configuration:configuration) // call your startup handler closure

    ... // do some stuff

    let isRunning = false // replace with actual logic
    let error = nil // replace with your actual error detection

    completion(isRunning: isRunning, error: error) // call completion closure
}

然后您可以这样调用它:

start(
    { configuration in

        // do something with your configuration

    }, completion: {isRunning, error in

        // do something with your isRunning & error.

})

使用语法(arguments) -> (returns) 定义闭包,您可以使用输入替换arguments并使用outputs返回(非常类似于定义函数的方式) )。

在您的情况下,您的闭包不会返回任何内容,因此我们将它们定义为:

(isRunning:Bool, error:NSError?) -> ()

(其中空元组()用于表示没有返回任何内容)

然后创建它们,并使用以下简写符号将它们传递给函数(如果已知闭包的参数类型):

closureArgument: { (arguments here, without types as they're known) in

}

closureArgument: { isRunning, error in 

}

将它们传递给函数的更正式的方法是:

closureArgument: { (arguments with types) -> (returns with types) in

}

closureArgument: { (isRunning:Bool, error:NSError?) -> () in 

}

然后,您可以调用闭包,就像调用函数一样。

closureArgument(isRunning: false, error: nil)

我发现this site非常适合引用闭包语法(并且可能比我更好地解释它)。

答案 1 :(得分:3)

我确定其他人会通过示例代码为您提供非常详细的答案,所以我只是提到这一点以供将来参考:

如何在Swift中声明闭包?

来自fuckingclosuresyntax.com或SFW版本goshdarnclosuresyntax.com

  

作为变量

var closureName: (ParameterTypes) -> (ReturnType)
     

作为可选变量

var closureName: ((ParameterTypes) -> (ReturnType))?
     

作为类型别名

typealias ClosureType = (ParameterTypes) -> (ReturnType)
     

作为常数

let closureName: ClosureType = { ... }
     

作为函数调用的参数

func({(ParameterTypes) -> (ReturnType) in statements})
     

作为功能参数

array.sort({ (item1: Int, item2: Int) -> Bool in return item1 < item2 })
     

作为具有隐含类型的函数参数

array.sort({ (item1, item2) -> Bool in return item1 < item2 })
     

作为具有隐含返回类型的函数参数

array.sort({ (item1, item2) in return item1 < item2 })
     

作为最后一个功能参数

array.sort { (item1, item2) in return item1 < item2 }
     

作为最后一个参数,使用速记参数名称

array.sort { return $0 < $1 }
     

作为最后一个参数,带有隐含的返回值

array.sort { $0 < $1 }
     

作为最后一个参数,作为对现有功能的引用

array.sort(<)
     

作为具有显式捕获语义的函数参数

array.sort({ [unowned self] (item1: Int, item2: Int) -> Bool in return item1 < item2 })
     

作为具有显式捕获语义和推断的函数参数   参数/返回类型

array.sort({ [unowned self] in return item1 < item2 })
     

本网站并非旨在列出闭包所有可能用途的详尽清单。

答案 2 :(得分:2)

为了理解闭包是如何工作的,我已经分离了闭包的定义,而没有将它内联到方法签名。您可以执行以下操作:

func start(startupHandler: (configuration: WTStartupConfiguration) -> Void, completion: (isRunning: Bool, error: NSError) -> Void ) {
    //Your code for start method
}

var startupHandlerClosure = { (configuration: WTStartupConfiguration) -> Void in
    //Your code for startupHandler closure
}

var completionClosure = { (isRunning: Bool, error: NSError) -> Void in
    //Your code for completion closure
}

//Method call
start(startupHandlerClosure, completion: completionClosure)

@ originaluser2打败了我..他提供了附加代码示例。