Swift 扩展中的参数类型未正确显示

Parameter types not shown correctly from Swift extension

我正在替换应用程序中的一些 Obj-C,其中 NSDictionary 上有一个类别,我需要在 Swift 扩展中使用相同的功能。我已经编写了扩展程序并拥有一个干净的构建,但是在尝试使用扩展程序时无法识别我的参数类型。该函数接受一个NSData类型的参数,但在调用它时,将NSData对象传递给该函数会导致编译错误。

分机:

extension NSDictionary {
    func getJsonDictionaryForData(data:NSData) -> NSDictionary {
        var geoDict:NSDictionary = NSDictionary()
        do {
            geoDict = try NSJSONSerialization.JSONObjectWithData(data, options: []) as! NSDictionary
        }
        catch let error as NSError {
            print("ERROR: \(error.description)")
        }
        return geoDict
    }
}

调用扩展的 getJsonDictionaryForData 函数时,XCode 期望参数类型为扩展函数声明中定义的 NSDictionary 而不是 NSData。下面的屏幕截图显示 XCode 在调用函数时需要 NSDictionary。我对 Swift 扩展比较陌生,所以显然这是我的错误。谁能帮我理解为什么会这样?谢谢!

// contextData is an NSData object and causes a compile error - wrong data type
let fileDict = NSDictionary.getJsonDictionaryForData(contextData) 

您是说:

 NSDictionary.getJsonDictionaryForData

好像这是一个 class 方法。但是在您的扩展中,您将其定义为 instance 方法。所以:

  • 如果你想要一个class方法,你应该说class func

  • 如果你想要一个实例方法,你应该在一个实际的字典上调用这个方法,而不是在 class NSDictionary 上。

(顺便说一句,编译器和代码完成所说的实际上是正确的,因为 Swift 中的实例方法是柯里化的 class 方法。因此,当您尝试调用此实例方法作为 class 方法,您会看到隐藏的 class 方法的签名。但这可能比您真正需要的技术信息更多。)

@matt 是正确的,您试图将该函数作为静态方法调用。但是,您也可以通过将其设为 init 来改进扩展本身。

extension NSDictionary {
    convenience init(data: NSData) throws {
        self.init()
        self.setValuesForKeysWithDictionary(
            try NSJSONSerialization.JSONObjectWithData(data, options: []) as! [String:AnyObject]
        )
    }
}

现在您可以这样做了:

do {
    let dictionary = try NSDictionary(data: jsonData)
} catch {
    print(error)
}