我在一个应用程序中替换了一些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)
答案 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)
}