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

时间:2016-09-08 16:42:32

标签: ios swift swift-extensions

我在一个应用程序中替换了一些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 NOT NSData,如扩展的函数声明中所定义。下面的屏幕截图显示了XCode在调用函数时期望NSDictionary。我对Swift扩展相对较新,所以很明显这是我的错误。任何人都可以帮助我理解为什么会这样吗?谢谢!

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

enter image description here

2 个答案:

答案 0 :(得分:1)

你在说:

 NSDictionary.getJsonDictionaryForData

好像这是方法。但是在您的扩展中,您将其定义为实例方法。所以:

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

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

(顺便说一句,编译器和代码完成所说的实际上是正确的,因为Swift中的实例方法是一个curried类方法。因此,当你尝试将这个实例方法称为类方法时,你是看到隐藏类方法的签名。但这可能是你真正需要的技术信息。)

答案 1 :(得分:1)

@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)
}