2015-12-29 5 views
0

Я больше не вижу, как Xcode жалуется, что некоторые вещи нуждаются в дополнительных вариантах («?»). Теперь он всегда принудительно разворачивается (удар »!). Есть ли причина использовать дополнительные опции, когда мы теперь вынуждены развернуть?Почему Swift 2 предпочитает принудительное разворачивание по сравнению с опциями?

ответ

1

Я не знаю, что вы имеете в виду, когда пишете, что вы больше не видите, что Xcode жалуется, что «некоторые вещи нуждаются в дополнительных вариантах. Теперь он всегда принудительно разворачивается». Эти два предложения противоречат друг другу:

  • Возможно, у вас могут быть необязательные переменные столько, сколько вы пожелаете, но необязательно может быть действительно приятно, когда вы узнаете все преимущества их использования.
  • Если у вас есть свойство, которое не является необязательным, тогда по определению не потребуется развертывание.

Возможно, что вы Мент в том, что, казалось бы, Xcode жалуется реже , когда вы на самом деле сила разворачивать опциями, или, как плохая привычка Xcode, подсказывает вам, чтобы заставить UnWrap вещи, чтобы избежать ошибок компиляции времени. Это, как правило, потому, что Xcode не может знать во время компиляции, что вы просто написали код, который разорвет ваше приложение во время выполнения.

Xcode может показаться, что время от времени имеет только одну цель с его «умными подсказками»: а именно, чтобы освободить ошибки времени компиляции. Если вы попытаетесь присвоить значение типа String? (необязательно String) в размере String, Xcode сообщит вам об ошибке компилятора и спросит, хотите ли вы добавить оператора принудительной разворачивания !. Смарт Xcode, вы говорите? Meh, Xcode хорош для многих вещей, но решение о том, как вы разворачиваете свои опционы, в любом случае не является одним из них. Таким образом, даже с Xcode, предлагающим вам всевозможные вещи: если вы можете использовать необязательную цепочку, сделайте.

Может быть, конечно, исключение. Для части контроллера, относящейся к проектной модели MVC, вы обычно используете оператор as! для принудительного преобразования (casting), при этом Xcode иногда говорит вам явно использовать as! вместо as, например. "Возможно, вы имели в виду as! ...?". В этих ситуациях Xcode иногда может действительно знать, что делает и делает вывод о том, что вы пытаетесь использовать в качестве примера пользовательский экземпляр класса UIViewController для ввода UIViewController, то есть его родительского класса. Я бы сказал, что это, пожалуй, один из немногих раз, когда я использую «принудительный» маркер ! без обхода; принудительное преобразование к типам, которые я знаю, со 100% уверенностью в том, что их можно использовать.

Но давайте оставим тему преобразования типа/литья и перейти к дополнительным видам, обертывание и опционального цепочки, в целом.


Как правило, следует избегать силы разворачивания, если явно не знает, что объект вы разворачивать будет не равен нулю.Для свойств общего класса, переменные и так далее, при условии, что вы утверждаете этот вопрос, как и вы, я дам вашему следующий совет:

Если вы можете использовать условные развёртки (if-let, guard-let, ноль коагуляторный оператор ??), затем не использовать принудительная разворачивание (!).

Ниже приведен пример опасности принудительной разворачивания. Вы можете рассматривать первый пункт if (if arc4random...) как любой меньший или больший сегмент некоторой программы, которую вы написали с помощью императивных методов программирования: мы действительно не знаем подробно, как «имя» получится до выполнения, а наш компилятор не может действительно помочь нам здесь.

var name : String? 

/* 'name' might or might not have a non-nil 
    value after this if clause */ 
if arc4random_uniform(2) < 1 { 
    name = "David" 
} 

/* Well-defined: us an if-let clause to try to unwrap your optional */ 
if let a = name { 
    print("Hello world "+a) 
     /* Very well-behaved, we did a safe 
      unwrap of 'name', if not nil, to constant a */ 

    print("Hello world "+name!) 
     /* Well... In this scope, we know that name is, 
      for a fact, not nil. So here, a force unwrap 
      is ok (but not needed). */ 
} 

let reallyGiveMeThatNameDammit = name! 
    /* NOT well-defined. We won't spot this at compile time, but 
     if 'name' is nil at runtime, we'll encounte a runtime error */ 

Я рекомендую вам прочитать дополнительную цепочку, ключевую тему в Swift.

+0

Спасибо за отличный ответ. Я предполагаю, что для Xcode вместо того, чтобы делать «if let» или используя «guard», он просто бросает молоток на все, что угодно, то есть на удар «!». – 4thSpace

+0

@ 4thSpace Счастливые помочь. Да, я тоже это почувствовал. Однако, как только вы узнаете, что Xcode поможет вам удалить ошибки времени компиляции (иногда с использованием первых возможных средств), вы можете использовать «подсказки», которые они дают вам (особенно при принудительной разворачивании), как хороший маркер для реализации ваша дополнительная цепочка. – dfri

0

вы имеете в виду, что материал какао? вы подразумеваете неявно развернутый?

protocol AnyObject { ... } 

Протокол, к которому все классы неявно соответствуют.

При использовании в качестве конкретного типа все известные методы и свойства @objc доступны как неявно-разворачиваемые необязательные методы и свойства соответственно для каждого экземпляра AnyObject. Например:

class C { 
    @objc func getCValue() -> Int { return 42 } 
} 

// If x has a method @objc getValue()->Int, call it and 
// return the result. Otherwise, return nil. 
func getCValue1(x: AnyObject) -> Int? { 
    if let f:()->Int = x.getCValue { // <=== 
    return f() 
    } 
    return nil 
} 

// A more idiomatic implementation using "optional chaining" 
func getCValue2(x: AnyObject) -> Int? { 
    return x.getCValue?() // <=== 
} 

// An implementation that assumes the required method is present 
func getCValue3(x: AnyObject) -> Int { // <=== 
    return x.getCValue() // x.getCValue is implicitly unwrapped. // <=== 
} 
+0

Нет. Это iOS и ничего общего с материалом @objc. – 4thSpace

+0

iOS только? и что относительно OSX? Рамки какао и CocoaTouch - все @objc ... поэтому, пожалуйста, предоставьте нам пример, о котором вы говорите. – user3441734