Проверьте вывод, типа для url
. (Вы можете сделать это, нажав опцию, щелкнув имя переменной в любом месте, где оно используется.) Вы найдете это тип NSURL?
(aka Optional<NSURL>
), а не NSURL
. Для инициализатора NSXMLDocument
init?(contentsOfURL:options:error:)
требуется необязательный URL-адрес, поэтому ваш вызов этого инициализатора завершит проверку типов ... и затем выдаст ложное сообщение об ошибке.
(Из-за того, что он не прошел проверку типа, предполагается, что вы пытаетесь вызвать другой инициализатор ... если бы это было так, ваша проблема была бы в том, что у вас неправильные аргументы. Возможно, стоит filing a bug.)
Вы получаете необязательный вызов NSURL(string:)
, потому что этот инициализатор failable. Если вы передаете строку, которая не является допустимым URL, этот инициализатор возвращает nil вместо действительного экземпляра NSURL
. Swift довольно серьезно относится к тому, чтобы убедиться, что вы знаете и правильно обрабатываете возможные нули в коде, потому что в противном случае они могут вызвать проблемы для вашего приложения.
Вашего решения форс-разворачивания опциональный (пропускание url!
к NSXMLDocument
) «работает» в том, что она удовлетворяет компилятор: Вы удостоверились, что значение передается в NSXMLDocument
имеет неопциональных NSURL
типа. Но вы на самом деле не справились с возможным nil - если ваш url действительно ничто, ваше приложение будет разбиваться по этой линии. Это безопасно до test optionals for nil, прежде чем использовать их - и вы действительно должны это сделать в этом случае, потому что содержимое вашей строки может измениться во время выполнения, возможно, создав фиктивный URL.
Кроме того, у вас есть несоответствие типа в параметре options
тоже: Необработанный тип NSXMLDocumentContentKind
перечисления UInt
, но тип, ожидаемый этот параметром является Int
. Вы можете конвертировать его с помощью Int(NSXMLDocumentContentKind.XMLKind.rawValue)
. (Это, безусловно, стоит filing a bug о - интерфейсы Apple должны следить за соответствием типов перечислений и инициализаторов.)
Наконец, несвязанный совет: Вы используете var
для всех, но вы (насколько вы показали) никогда не меняется, что ваши переменные указывают. Используйте let
для вещей, которые не меняются, например url
, category
и, возможно, document
(помните, что вы можете иметь постоянную ссылку на изменяемый объект). Это позволяет компилятору помочь вам убедиться, что ваш код верен и может (теоретически, по крайней мере) помочь ему генерировать оптимизированный код во время сборки.
Благодарим за предоставленный общий метод, чтобы узнать, где была ошибка (и эти советы)! И да, я напишу отчет об ошибке. И спасибо за упоминание провального инициализатора, я слышал этот термин, но никогда не понимал, что это происходит, хотя именно это я искал для некоторых из моих классов. –