Swift 有没有一种方法可以在不重新指定所有参数的情况下调用函数本身?
如果有人能想出另一种方法来实现我的目标,欢迎你的想法 为了让大家了解一下,我有40多个不同的函数,它们的签名与以下类似:Swift 有没有一种方法可以在不重新指定所有参数的情况下调用函数本身?,swift,asynchronous,recursion,closures,completionhandler,Swift,Asynchronous,Recursion,Closures,Completionhandler,如果有人能想出另一种方法来实现我的目标,欢迎你的想法 为了让大家了解一下,我有40多个不同的函数,它们的签名与以下类似: func getXFromServer(arg1: String, arg2: Int, arg3: Bool, completion: ((MyCustomResponse)->Void)? = nil) func getYDataFromServer(completion: @escaping (Bool)->Void) func getZDataFromSe
func getXFromServer(arg1: String, arg2: Int, arg3: Bool, completion: ((MyCustomResponse)->Void)? = nil)
func getYDataFromServer(completion: @escaping (Bool)->Void)
func getZDataFromServer(arg1: Int, completion: @escaping (MyGeneric<MyClass>)->Bool)
我目前正在处理handleServerResponse
之外的重新执行,如下所示:
func getYDataFromServer(completion: @escaping (Bool)->Void)
{
session.dataTask(with: URLRequest()) { data, response, error in
handleServerResponse(){ valid
if !valid
{
self.getXYZDataFromServer(){
getYDataFromServer(completion: completion)
}
return
}
//do more stuff with Y server data
}
}.resume()
}
这是一个非常简单的代码版本,但正如您所看到的,它很快就会得到大量重复的代码
谢谢也许这会有帮助
func getData(_ args: Any..., completion: @escaping ((Any)->Any)){
print(args)
completion(11)
}
但函数类型不能强制任何一个,您可以考虑使用枚举来组合安全类型。
var valid: Bool = false
func getXFromServer(arg1: String, arg2: Int, arg3: Bool, completion: ((String)->Void)? = nil){}
func getYDataFromServer(completion: @escaping (Bool)->Void){
// session.dataTask(with: URLRequest()) { data, response, error in
// handleServerResponse(){ valid
valid.toggle()
print(valid)
if valid
{
MixGetData.XYZ.run{ MixCompletion.XYZ{ firstY.run{MixCompletion.Y(completion) } }}
}
else {
completion(false)
}
// }
// }.resume()
}
func getZDataFromServer(arg1: Int, completion: @escaping (String)->Bool){}
func getXYZDataFromServer(completion: @escaping ()->Void){
completion()
}
enum MixCompletion{
case X(((String)->Void)?)
case Y((Bool)->Void)
case Z((String)->Bool)
case XYZ(()->Void)
}
enum MixGetData{
case X( String, Int, Bool )
case Y
case Z(Int)
case XYZ
func run(completion: (() -> MixCompletion)? = nil){
if (completion == nil) {
switch (self) {
case let .X(arg1, arg2, arg3) : getXFromServer(arg1: arg1, arg2: arg2, arg3: arg3, completion : nil)
case let .Z(arg1) : getZDataFromServer(arg1: arg1, completion: {_ in return false})
case .Y : getYDataFromServer(completion: {_ in})
case .XYZ : getXYZDataFromServer(completion: {})
}}
else {
switch (self, completion!()) {
case (let .X(arg1, arg2, arg3), let .X(comp)): getXFromServer(arg1: arg1, arg2: arg2, arg3: arg3, completion : comp)
case (let .Z(arg1), let .Z(comp) ) : getZDataFromServer(arg1: arg1, completion: comp)
case (.Y, let .Y(comp)) : getYDataFromServer(completion: comp)
case (.XYZ, let .XYZ(comp)) : getXYZDataFromServer(completion: comp)
default: break
}
}
}
}
let firstY = MixGetData.Y
firstY.run()
firstY.run{MixCompletion.Y{bool in print (bool)}}
另一种方法是使用泛型函数。此外,您还可以将两者结合使用:
func getYDataFromServer(completion: @escaping (Bool)->Void){
// session.dataTask(with: URLRequest()) { data, response, error in
// handleServerResponse(){ valid
valid.toggle()
print(valid)
if valid
{
getData(name: "XYZ", array: "") { getData(name: "Y", array: "", completion: completion)}
}
else {
completion(false)
}
// }
// }.resume()
}
func getData<T>(name: String , array: Any... , completion: T ){
switch name {
case "Y":
getYDataFromServer(completion: completion as! (Bool)-> Void)
case "X":
let arg1 = array[0] as! String; let arg2 = array[1] as! Int; let arg3 = array[2] as! Bool
getXFromServer(arg1: arg1, arg2: arg2, arg3: arg3, completion: completion as? (String)-> Void)
case "Z":
let arg1 = array[0] as! Int
getZDataFromServer(arg1: arg1, completion: completion as! (String)-> Bool)
case "XYZ":
getXYZDataFromServer(completion: completion as! ()-> Void)
default:
break;
}
}
getData(name: "Y", array : "", completion: { bool in print (123) } as (Bool)-> Void )
这对我很有效 嗨,谢谢你花时间回复。不幸的是,如果我仍然需要在不同的类型上切换,这些方法就不是我想要的。
func getYDataFromServer(completion: @escaping (Bool)->Void){
// session.dataTask(with: URLRequest()) { data, response, error in
// handleServerResponse(){ valid
valid.toggle()
print(valid)
if valid
{
getData(name: "XYZ", array: "") { getData(name: "Y", array: "", completion: completion)}
}
else {
completion(false)
}
// }
// }.resume()
}
func getData<T>(name: String , array: Any... , completion: T ){
switch name {
case "Y":
getYDataFromServer(completion: completion as! (Bool)-> Void)
case "X":
let arg1 = array[0] as! String; let arg2 = array[1] as! Int; let arg3 = array[2] as! Bool
getXFromServer(arg1: arg1, arg2: arg2, arg3: arg3, completion: completion as? (String)-> Void)
case "Z":
let arg1 = array[0] as! Int
getZDataFromServer(arg1: arg1, completion: completion as! (String)-> Bool)
case "XYZ":
getXYZDataFromServer(completion: completion as! ()-> Void)
default:
break;
}
}
getData(name: "Y", array : "", completion: { bool in print (123) } as (Bool)-> Void )
func handleServerResponse<T, U>(_ alternative : (T) -> () , _ completion : @escaping (U) -> (), _ handler : U , _ terminator : () , _ resValid : Bool){
if resValid {
alternative( completion(handler) as! T )
}
else {
terminator
}
}
func getYDataFromServer(completion: @escaping (Bool)->Void){
response.toggle()
// session.dataTask(with: URLRequest()) { data, response, error in
handleServerResponse({(a) in getXYZDataFromServer {a
}}, { (a: @escaping (Bool)->Void) in getYDataFromServer(completion: a) }, completion, completion(true), response)
handleServerResponse( { (a) in getXYZDataFromServer{a}} , { (a: @escaping (Bool)->Void) in getZDataFromServer(arg1: 1, completion: { (s) -> Bool in
a
return false
})}, completion, completion(true), response)