Почему свойство текста UITextField было изменено на необязательное в Swift 2?

В соответствии с документом UIKit diff в ios9/Swift 2

var text: String! стал var text: String?

В соответствии с документацией для UITextField он определенно говорит

This string is @"" by default.

Я не понимаю цели этого изменения. Должно ли это свойство всегда быть пустой строкой, если текстовое поле существует вообще? В какой момент это поле возвращает пустую строку? Как только пользователь взаимодействует с ним? Как только он будет добавлен в иерархию представлений? В какой момент он возвращает nil?

Если текстовое поле существует в первую очередь, всегда ли безопасно предположить, что свойство text существует? Это похоже на то, что это приведет к большому количеству find/replace .text до .text!

Я не вижу, где он упоминается в документах, поэтому, возможно, у кого-то есть предыстория или помощь в том, почему это изменилось.

Ответ 1

Короче говоря, (ответ на заголовок) это не так.

Подробнее:

Для меня гораздо более важно иметь его как необязательный, который не принудительно разворачивается. Apple нажимает на разработчиков, чтобы никогда не использовать optional!, и имеет смысл только то, что они применяют те же правила к API.

Причиной этого является то, что он может быть равен нулю, и это не имеет никакого значения, если он объявлен с помощью ? или ! для запуска кода. Использование ! фактически просто удаляет предупреждения в Xcode, которые действительно удобны, особенно когда дело доходит до кода API. Если вы не понимаете, что на самом деле это необязательно, вы просто просите о проблемах.

Проверка на nil также намного удобнее теперь с guard, и вы можете связать это с проверкой на "", чтобы она больше не работала.

В общем случае опции лучше, потому что что-то, что нет, не использует память. Чем больше вариантов мы получили, тем легче мы можем сделать наши приложения. Также он даже не выглядит плохим и не добавляет к пирамиде обреченности.

Этот пример возьмет обе строки в качестве аргументов, удалит ? в параметре func, и Xcode будет там, чтобы вас предупредить.

Я забыл ответить на эту часть напрямую: Это становится нулевым, когда вы устанавливаете его на nil, что вы можете сделать, чтобы сохранить немного памяти. Просто нет смысла иметь возможность установить его на нуль и не иметь xcode, чтобы вы правильно его обрабатывали. = > Это невозможно...

var forcedUnwrappedString : String! = ""
var optionalString : String? = ""

forcedUnwrappedString = nil
optionalString = nil

func doSomethingWithString(string : String?) -> String? {
    guard var unwrappedString = string else {
        // error handling here
        return nil
    }
    let tempString = unwrappedString + "!"

    return tempString
}

func doSomethingUnsafeWithString(string : String) -> String {

    let tempString = string
    return tempString

}

var newString = doSomethingWithString(optionalString)
var newString2 = doSomethingWithString(forcedUnwrappedString)

newString = doSomethingUnsafeWithString(optionalString!) // this will crash without a warning fro xcode
newString2 = doSomethingUnsafeWithString(forcedUnwrappedString) // this will crash without a warning fro xcode

Обновление:

В текстовом свойстве UITextfield есть наборщик, который всегда устанавливает "" в случае nil, не знает об этом нигде в документах или файлах UIKit.h.

var textField = UITextField(frame: CGRect(x: 0, y: 0, width: 0, height: 0))
var string = textField.text // string = ""
textField.text = nil
string = textField.text // string = ""

Ответ 2

Простым способом решения этой проблемы является создание расширения для UITextField и использование этого вместо свойства .text.

extension UITextField {
    var unwrappedText: String {
        return self.text ?? ""
     }
}

Теперь вы можете сказать textfield.unwrappedText, не беспокоясь о опциях. (Конечно, это просто для чтения значения).

Ответ 3

Как заметил сам Менке, на самом деле невозможно установить text на ноль. Очевидно, Apple хочет, чтобы он был документирован как обнуляемый, несмотря на текущую реализацию, и для меня это не имеет никакого смысла - я имею в виду, не имеет для меня достаточного смысла. Дело в том, что для Apple это определенно не "неправильно", но является ли это элегантным способом делать все для каждого? Очевидно нет. И если вы не согласны с ними, не волнуйтесь, вам совершенно не нужно оставлять свои мнения по некоторым решениям Apple.

Итак, какова цель этого изменения? Возможно, они начали внутреннее правило, в котором говорилось, что никогда не делают какие-либо свойства компонентов UIKits недействительными для согласованности. Возможно, они думают теоретически, что свойство текста может быть выпущено из-за давления памяти в крайнем случае. Как бы то ни было, я не думаю, что они действительны, но мы должны повиноваться. Это, однако, не делает меня фанатом.

Ответ 4

Также вы можете использовать этот хак с символом Unicode:

extension UITextField {
    var teхt: String { //"х" is U+0445 unicode character
        return self.text ?? ""
    }
}