【问题标题】:How to use block/closure in swift如何在 swift 中使用块/闭包
【发布时间】:2015-10-08 01:30:24
【问题描述】:

在我的一个应用程序中,我使用了块来调用 Web 服务并获得响应。现在我想用 swift 编写这个应用程序,但是在 Swift 中使用块/闭包时遇到了麻烦。 这是我想快速迁移的目标 C 代码:

调用 Communicator 的类方法

[[Communicator sharedInstance]callWebService:WS_LOGIN withMethod:POST_METHOD andParams:params showLoader:YES completionBlockSuccess:^(id obj) {
   //Do play with data
}completionBlockFailiure:^(id obj) {
   //Show alert with error
}];

在通信器类中

-(void)callWebService:(NSString *)serviceName withMethod:(NSString *)methodName andParams:(NSDictionary *)params showLoader:(BOOL)showLoader completionBlockSuccess:(void (^)(id))aBlock completionBlockFailiure:(void (^)(id))aFailBlock
{
   if (showLoader) {
   // show loader
   }
   [self performRequestWithServiceName:serviceName method:methodName andParams:params successblock:aBlock failureblock:aFailBlock];
}

- (void)performRequestWithServiceName:(NSString *)serviceName method:(NSString*)methodName andParams:(NSDictionary*)params
                 successblock:(void (^)(id obj))successBlock
                 failureblock:(void (^)(id obj))failBlock {
   if(callSuceess){
      successBlock(@"Success");
   }else{
      successBlock(nil);
   }
}

【问题讨论】:

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


    【解决方案1】:

    对于斯威夫特。 id objc 类型使用 AnyObject。

    func callWebservice (serviceName: String, withMethod method: String, andParams params: NSDictionary, showLoader loader: Bool, completionBlockSuccess aBlock: ((AnyObject) -> Void), andFailureBlock failBlock: ((AnyObject) -> Void)) {
        if loader {
            // Show loader
        }
    
        performRequestWithServiceName(serviceName, method: method, andParams: params, success: aBlock, failure: failBlock)
    }
    
    func performRequestWithServiceName(serviceName: String, method methodName: String, andParams params: NSDictionary, success successBlock: ((AnyObject) -> Void), failure failureBlock: ((AnyObject) -> Void)) {
        if callSuceess {
            successBlock("Success")
        }else {
            successBlock(nil)
        }
    }
    

    更新:当您想致电web service 时的示例。见下方代码

    callWebservice("your-service-name", withMethod: "your-method", andParams: ["your-dic-key": "your dict value"], showLoader: true/*or false*/, completionBlockSuccess: { (success) -> Void in
        // your successful handle
    }) { (failure) -> Void in
        // your failure handle
    }
    

    【讨论】:

    • 伟大的 +1 完整的答案
    • @Ashish Kakkad。谢谢
    • @longpham 你能帮我从我的视图控制器调用 callWebservice 方法吗?我在快速设置参数时遇到了麻烦。提前致谢。
    • @Mayank Jain。在这里学习一个闭包教程:goshdarnclosuresyntax.com。我只是根据您的要求更新我的答案。
    【解决方案2】:

    您的代码可能如下所示:

    func callWebService(serviceName: String, method: String, params: [String : AnyObject], showLoader: Bool, success: (responseObject: AnyObject) -> Void, failure: (responseObject: AnyObject) -> Void) {
        if showLoader {
            // show loader
        }
    
        performRequest(serviceName, method: method, params: params, success: success, failure: failure)
    }
    
    func performRequest(serviceName: String, method: String, params: [String : AnyObject], success: (responseObject: AnyObject) -> Void, failure: (responseObject: AnyObject) -> Void) {
    
    }
    

    我将NSDictionary 替换为[String : AnyObject]。如果您可以将AnyObject 的任何用法替换为更具体的类型,您的代码将会更干净、更稳定。

    【讨论】:

      【解决方案3】:

      对于 Swift Closures,我们必须使用 ( ) -> ( )

      例如:

      func yourFunction(success: (response: AnyObject!) -> Void, failure: (error: NSError?) -> Void) {
      
      }
      

      你可以这样称呼它:

      yourFunction({(response) -> Void in
          // Success
      }) { (error) -> Void in
          // Handle Errors
      }
      

      希望它能帮助您根据您的要求创建闭包。

      【讨论】:

      • 我猜是调用函数有语法错误。
      • @MayankJain 哦!。更新了答案。希望它对你有用
      【解决方案4】:

      在 communicator 类中,调用 web 服务的方法将根据您要返回的对象的类型进行定义

      func performRequest(serviceName: NSString, methodName: NSString,paramaters:NSDictionary, successblock: (String)->(), failureBlock: () -> ()) {
          if(callSuccess) {
              successblock("Success")
          } else {
             failureBlock() 
      }
      

      我们通过函数签名来定义成功和失败块类型,在上面的例子中,成功被定义为一个将字符串作为输入参数并且不返回任何内容的方法,因此我们可以调用 successBlock 传入字符串。上面将失败块定义为不带参数且不返回任何内容的块。

      调用这个方法

      func callWebService(serviceName: NSString, method: NSString and parameters: NSDictionary, showLoader: Bool, completionBlockSuccess:(String) -> (), completionBlockFailiure:() -> ()) {
          if (showLoader) {
          // show loader
          }
          performRequest(serviceName: serviceName, methodName: method, parameters, successBlock:completionBlockSuccess, failureBlock: completionBlockFailiure)
      }
      

      终于可以这样称呼了

      Communicator.sharedInstance().callWebService(serviceName: WS_LOGIN , method: POST_METHOD and parameters: params, showLoader: true, completionBlockSuccess:{ returnedString in
      
           //Do play with data
      
      }, completionBlockFailiure:{ 
      
          //Show alert with error
      
      })
      

      对于完成块,我们定义了一个变量 returnedString 以允许我们操作该输入参数(在上面的示例中,它将是字符串“Success”)。我假设您的数据不只是返回一个字符串,因此您可能需要根据您的服务返回的内容来处理它们的类型。

      此外,我尝试使用 NSString 和 NSDictionary 来匹配您的方法签名,但根据您的需要,Swift 等效字符串和 [String: AnyObject] 可能更合适。

      【讨论】:

        【解决方案5】:
        func processingWithAnyObject(input: String, completion: @escaping (_ result: AnyObject) -> Void) {
            ...
            completion(response.result.value! as AnyObject)
        }
        
        processingWithAnyObject("inputString") {
            (result: AnyObject) in
            print("back to caller: \(result)")
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2017-10-15
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多