2015-10-28 3 views
8

Следующий код бросает сообщение, которое говорит„инициализатор для условной привязки должны иметь факультативный тип, а не „AnyObject““Initializer для условной привязки должны иметь факультативный тип, а не «AnyObject - подход

func parseData2(){ 
     var data:NSData? 


     if let data2 = data { 
      do { 
       let details = try NSJSONSerialization.JSONObjectWithData(data2, options: .AllowFragments) 

       if let actualDetails = details where actualDetails.isKindOfClass(NSDictionary) { 
        print("Parse Data") 
       } 

      }catch { 
       print("Error \(error)") 
      } 
     } 

    } 

Для устранения выше ошибки Я использовал следующий код.

func parseData2(){ 
     var data:NSData? 


     if let data2 = data { 
      do { 
       let details:AnyObject = try NSJSONSerialization.JSONObjectWithData(data2, options: .AllowFragments) 

       if let actualDetails:AnyObject = details where actualDetails.isKindOfClass(NSDictionary) { 
        print("Parse Data") 
       } 

      }catch { 
       print("Error \(error)") 
      } 
     } 

    } 

Есть ли какой-нибудь лучший подход, чем выше, или мой код может упасть?

Существует еще один код, который я хочу добавить, учитывая ноль проверить, тип проверки, а затемтип проверки литых. Причина в том, что Swift предлагает большую гибкость, но немного легче решить проблемы. Предположим, у меня есть словарь, cityDetails, и я пытаюсь получить данные для self.cityZipCode и self.cityIdentifier, которые являются необязательными, как var cityZipCode: Int? и var cityIdentifier: Int?

if let cityBasic = cityDetails["basicDetails"] where 
cityBasic!.isKindOfClass(NSDictionary) { 

self.cityZipCode = (cityBasic as! NSDictionary)["zip"].integerValue ?? 0 

self.cityIdentifier = (cityBasic as! NSDictionary)["cityId"].integerValue ?? 0 

} 
+0

Я не понимаю, что вы спрашиваете в обновлении своего вопроса? Либо уточните, как это относится к первой части, либо задайте новый вопрос для новой части. В настоящий момент ваш заголовок ссылается на проблему «Необязательный Binding», ваша первая часть посвящена 'do try catch', и теперь речь идет о' down casting' и 'nil coalescing operator' –

+0

. Я немного путаюсь с nil check, type check и затем опускание, как все это работает вместе? Простой код, но для этого требуется большое понимание. – andyPaul

+1

[is and as] (http://www.codingexplorer.com/type-casting-swift/), [необязательное связывание] (http://www.codingexplorer.com/multiple-optional-bindings-swift-1- 2 /), [do try catch] (https://www.hackingwithswift.com/new-syntax-swift-2-error-handling-try-catch). Google - ваш друг для общих языковых вопросов. Особенно, когда речь идет о наиболее написано о материалах –

ответ

5

Не нужно разворачивать результат от try. Это необязательно. Вам нужно сделать результат от try до NSDictionary. Используйте as?, чтобы уменьшить его.

Лучшие практики: полный доступ к возвращаемой ошибки для хорошей обработки ошибок

func parseData2(){ 
    var data:NSData? 

    if let data2 = data { 
     do { 
      let details = try NSJSONSerialization.JSONObjectWithData(data2, options: .AllowFragments) 

      if let detailsDict = details as? NSDictionary { 
       print("Parse Data") 
      } else if let detailsArray = details as? NSArray { 
       print("array") 
      } 

     } catch { 
      print("Error \(error)") 
     } 
    } 
} 

Быстрый и грязный: обработка ошибок не для меня!

func parseData2(){ 
    var data:NSData? 

    if let data2 = data { 

     let details = try? NSJSONSerialization.JSONObjectWithData(data2, options: .AllowFragments) 

     if let detailsDict = details as? NSDictionary { 
      print("Parse Data") 
     } else { 
      print("details might be nil, or not an NSDictionary") 
     } 
    } 
} 

Bad Ass Mode: аварии являются особенности

func parseData2(){ 
    var data:NSData? 

    if let data2 = data { 

     let details = try! NSJSONSerialization.JSONObjectWithData(data2, options: .AllowFragments) as! NSDictionary 

    } 
} 

Некоторые дополнительные данные на нескольких разворачивает: падение ниже код в детской площадки.

struct SomeStruct { 
    var anOptional : Int? 
    init() { 
    } 
} 

func unwrapWithIfLet() { 

    if let unWrappedStruct = myStruct, let unWrappedSomething = unWrappedStruct.anOptional { 
     print("multiple optional bindings succeeded") 
     // both unWrappedStruct and unWrappedSomething are available here 
    } else { 
     print("something is nil") 
    } 
} 

func unwrapWithGuard() { 

    guard let unWrappedStruct = myStruct, let unWrappedSomething = unWrappedStruct.anOptional else { 
     print("something is nil") 
     return 
    } 
    print("multiple optional bindings succeeded") 
    // both unWrappedStruct and unWrappedSomething are available here 
} 


var myStruct : SomeStruct? 

//unwrapWithGuard() 
//unwrapWithIfLet() 

myStruct = SomeStruct() 
myStruct!.anOptional = 1 

unwrapWithGuard() 
unwrapWithIfLet() 
+0

Хорошо, если я не хочу использовать try catch и проверять две вещи, объект не nil и isKindOfClass NSArray. Как можно сделать простейшим способом. – andyPaul

+0

@andyPaul обновлено: заказывается от save до простого –

+2

Бонусные баллы за режим Bad Ass. –

1

Вы ищете as?, который пытается преобразовать вещь налево к типу справа, и возвращает NIL, если преобразование не представляется возможным:

let details = try NSJSONSerialization.JSONObjectWithData(data2, options: .AllowFragments) 

if let actualDetails = details as? NSDictionary { 
    print("Parse Data") 
} 

Вам редко нужно используйте isKindOfClass в Swift. Если вы его используете, спросите, почему, и подумайте, будет ли вместо этого работать as или as?.

+0

Что делать, если детали не являются нулевыми и являются NSArray? – andyPaul

+0

Ваш исходный код был явно проверен на NSDictionary, поэтому я предположил, что вам нужен был словарь для вашего синтаксического анализа. Если вы можете работать со словарем _or_ массивом, вам вообще не нужна проверка типа; просто удалите '.AllowFragments', и он будет использовать только словари и массивы. Пожалуйста, опишите более подробно, что вы пытаетесь выполнить. –

+0

[Ответить на удаленный комментарий от R Menke]: Из исходного кода казалось, что искатель пытался работать со словарем, и в этом случае им нужна переменная типа 'NSDictionary', и в этом случае' as? 'In условный разворот - правильный подход. Если их код анализатора должен выполняться _only_, если результатом является «NSDictionary», но на самом деле не нужны какие-либо словарные вызовы (что маловероятно, но возможно), тогда 'is' действительно будет подходящим. –