ребят, уточните, а чем конкретно отлчичаются записи типов: 
let property: Type 
и 
let property: Type!
я не совсем понимаю, когда нужно ставить знак ! у типа экземпляра, отсюда нет 100% понимания в том, что иногда делаю(
Также есть любопытный момент - крутые ребята, когда программируют крутые приложения, иногда не сразу инициализируют проперти, а сначала указывают просто тип, например:
var networkDataFetcher: NetworkDataFetcher!
а потом ниже такие:
init (networkDataFetcher  = NetworkDataFetcher())) {
        self.networkDataFetcher = networkDataFetcher
некоторые делают примерно так:
let vc: ViewController
а потом ниже где-нибудь инициализируют в какой-нибудь функции:
func kakaiaToFuncciya() {
…
vc = ViewCOntroller()
…
}
отсюда второй вопрос: почему некоторые ребята так делают, а не просто сразу инициализируют переменные, например 
let vc = ViewController() и var networkDataFetcher = NetworkDataFetcher()
Помогите с этими двумя вопросами как можете, плиз! 😒
Система следующая: перед использованием свойства должны иметь значения, т.е. должны быть инициализированы. Вариант 1: пишешь сразу само значение. var name = "stolenhen". Это обычное значение и переменная уже сразу инициализирована. Вариант 2: значения еще нет - var name: String Но есть инициализатор - init(...). И если ты создаешь экземпляр, то значение указываешь в этот момент по инициализитору. Вариант 3: значения нет и может не быть, например, обрыв связи и данные не дошли. В этом случае делаешь опционал. var name: String? Это означает, что у свойства уже есть значение, но оно специфическое, означает отсутствие значения, которое называется nil. Условно говоря, такое свойство или переменная могут хранить в себе два типа значений - обычное значение и nil. Nil дает возможность управлять ошибками при отсутствии обычных данных. И если свойство не имеет обычного значения, но имеет nil, то оно уже считается инициализированным. И потом, при его использовании, когда в него уже передано нормальное значение и если ты хочешь его дальше использовать, то его надо извлечь из опционала. Грубо говоря, конвертировать из опционала в обычное значение. Вариант 4, как уже  сказали, var name: String! означает, что на старте свойство хранит в себе nil, но при первом использовании у него гарантировано будет обычное значение. Это делается для экономии памяти. Восклицательный знак извлекает значение из опционала.