【问题标题】:Problems trying to port an Objective C completion block into Swift尝试将 Objective C 完成块移植到 Swift 时出现问题
【发布时间】:2015-05-28 09:11:16
【问题描述】:

我正在使用用 Objective C 编写的第三方库,方法如下:

- (void)manageServerResponse:(NSURLResponse*)response NSData:(NSData*)data andNSError:(NSError*)error onComplete:(void (^)(NSInteger kindOfError, NSDictionary*jsonResponse))onComplete;

当我将它移植到 swift 时,我会执行以下操作:

typealias ResponseCompletedBlock = (NSInteger, NSDictionary?) -> Void
...
let completedResponseMethod : ResponseCompletedBlock = {(kindOfError: NSInteger, jsonResponse: NSDictionary?) -> Void in
    self.onComplete(kindOfError, jsonResponse: jsonResponse)}

let responseManager: ResponseManager = ResponseManager.sharedResponseManager() as! ResponseManager
responseManager.manageServerResponse(response, 
    NSData: data, 
    andNSError: error, 
    onComplete: completedResponseMethod)

我收到此错误:

无法使用类型参数列表调用“manageServerResponse” '(NSURLResponse?, NSData: NSData?, andNSError: NSError?, onComplete: ResponseCompletedBlock)'

如果我将最后一句替换为

responseManager.manageServerResponse(response, 
    NSData: data, 
    andNSError: error, 
    onComplete: nil)

一切正常,所以我认为问题出在块结构上,但我尝试更改所有内容,但错误仍然存​​在。

你能帮忙吗?

【问题讨论】:

  • 我还没有 Swift 的经验,但是你有没有尝试让 NSDictionary 在你的 (NSInteger, NSDictionary?) -> Void 闭包中隐式展开?
  • 在 swift 块中,您通常需要明确地确定需要解包的内容。添加一个!或者 ?可能会解决问题。一般来说 !为我解决了...
  • 我已经尝试了几件事,包括添加!和 ?到 NSDictionary 参数。没有运气

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


【解决方案1】:

NSDictionary * 映射到 Swift 为 [NSObject : AnyObject]!, 因此响应块的类型应该是

typealias ResponseCompletedBlock = (Int, [NSObject : AnyObject]!) -> Void

因此

let completedResponseMethod = {(kindOfError: Int, jsonResponse: [NSObject : AnyObject]!) -> Void in
    // ...
}

找出正确的 Swift 函数签名的一种方法是在 Xcode 中使用 autocompletion: 你开始打字

 responseManager.manageServerResponse(

Xcode 建议

【讨论】:

  • @F.D.FDev:不客气! – 我添加了一些关于如何解决这类问题的信息。
  • 谢谢你,虽然我的 Xcode 拒绝在 Swift 文件中自动完成来自 ObjC 的代码......不知道为什么(如果你问的话,我已经删除了派生数据)
【解决方案2】:

Apple docs:

当您从 NSDictionary 对象桥接到 Swift 字典时,结果字典的类型为 [NSObject: AnyObject]

此外,除非 Objective-C 代码被注释为可空性,否则 Swift 字典是一个隐式解包的可选。因此,您的 typealias 应如下所示:

typealias ResponseCompletedBlock = (NSInteger, [NSObject : AnyObject]!) -> Void

我还建议将 NSInteger 更改为 Int

【讨论】:

    【解决方案3】:

    typealiascompletedResponseMethod 是您的程序运行所必需的吗?如果没有,这可能会解决您的问题:

    responseManager.manageServerResponse(response, NSData: data, andNSError: error, onComplete: { 
        $0, $1 in
        self.onComplete($0, jsonResponse: $1)
    }
    

    正如您的错误所暗示的,错误是由于类型不匹配造成的。如果您使用默认的本地参数,您将能够解决该特定问题。

    【讨论】:

    • 完全没有,我添加了类型别名只是为了尝试将所有问题分成几部分。其实一开始只是一行代码……
    猜你喜欢
    • 1970-01-01
    • 2010-10-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多