初始化 NSXMLDocument 时出现额外参数错误

Extra argument error when initializing NSXMLDocument

我正在尝试在 Swift 中创建一个 NSXMLDocument,但是当我尝试创建我的 NSXMLDocument 时,我在调用中收到了一个“额外参数 'contentsOfURL',这是我的代码:

var url = NSURL(string: "http://api.openweathermap.org/data/2.5/weather?q=\(self.cityField.stringValue)&mode=xml")
var category = NSXMLDocumentContentKind.XMLKind.rawValue
var error: NSError? = NSError()

var document = NSXMLDocument(contentsOfURL: url, options: category, error: &error)

我做错了什么?谢谢。

EDIT :实际上,用这个替换初始化:

var document = NSXMLDocument(contentsOfURL: url!, options: kNilOptions, error: &error)

有效,首先是选项参数有问题(而且我还必须打开 url),但是现在,我不知道如何 select具体选项,如果我想?这里有什么问题?

我弄清楚出了什么问题,有两个问题:
- 我不得不打开 NSURL
- 最大的问题是我的 NSXMLDocumentContentKind.XMLKind.rawValueUIntinit 期待 Int 所以我用这个替换了我的代码:

var url = NSURL(string: "http://api.openweathermap.org/data/2.5/weather?q=\(self.cityField.stringValue)&mode=xml")
var category = Int(NSXMLDocumentContentKind.XMLKind.rawValue)
var error:NSError?
var document = NSXMLDocument(contentsOfURL: url!, options: category, error: &error)

而且效果很好:)

检查 url 的类型推断。 (您可以通过在使用变量名称的任何地方按住 option 并单击变量名称来执行此操作。)您会发现它的类型为 NSURL?(也称为 Optional<NSURL>),而不是 NSURLNSXMLDocument 初始化器 init?(contentsOfURL:options:error:) 需要一个非可选的 url,因此您对该初始化器的调用无法通过类型检查...然后产生虚假的错误消息。

(因为它没有通过类型检查,所以它假定您正在尝试调用不同的初始化程序...如果是这样,您的问题确实是您有错误的参数。可能值得 filing a bug关于。)

你从你的 NSURL(string:) 调用中得到一个可选的,因为那个初始化器是 failable。如果您传递的字符串不是有效的 URL,则初始值设定项 returns nil 而不是有效的 NSURL 实例。 Swift 非常重视确保您了解并正确处理代码中可能存在的 nil,否则它们可能会给您的应用带来问题。

你强制解包可选的解决方案(通过将 url! 传递给 NSXMLDocument)"works" 因为它满足编译器:你已经确保传递的值to NSXMLDocument 是非可选的 NSURL 类型。但是您还没有真正处理可能的 nil — 如果您的 url 真的是 nil,您的应用程序将在该行崩溃。在使用它们之前 test optionals for nil 是最安全的——在这种情况下你真的应该这样做,因为你的字符串的内容可以在运行时改变,可能会创建一个伪造的 URL.

除此之外,options 参数也有类型不匹配:NSXMLDocumentContentKind 枚举的原始类型是 UInt,但该参数期望的类型是Int。您可以使用 Int(NSXMLDocumentContentKind.XMLKind.rawValue) 转换它。 (这绝对值得 filing a bug — Apple 的界面应确保枚举和初始化程序类型匹配。)


最后,一个不相关的提示:您对所有内容都使用了 var,但您(就您所展示的而言)从未更改变量指向的内容。对于不变的东西使用 let,例如 urlcategory,可能还有 document(请记住,您可以对可变对象有常量引用)。这让编译器可以帮助您确保您的代码是正确的,并且可以(至少在理论上)帮助它在构建时生成优化的代码。