2016-11-20 3 views

ответ

4

UINavigationController() и UINavigationController.init() точно такие же вещи. Вы можете проверить это, введя оба в игровое поле, а затем вариант -clicking на них. Оба приводят документацию для того же самого инициализатора.

Соглашение о Swift должно использовать только имя типа (без .init).

+2

Единственное место, где вы, кажется, нужно вызвать 'Init()' явно (насколько я могу сказать) является 'super.init()' при переопределении инициализатор ... –

+1

@NicolasMiari хорошая точка, но в качестве дополнения, однако, стоит отметить, что 'super' - это не тип, а специальный префикс Swift, используемый для доступа к методам и свойствам суперкласса (а не только' init (...) '). Его варианты использования и доступ больше похожи на экземпляр типа, а не самого типа (за исключением, в частности, инициализаторов суперкласса). – dfri

+0

Действительно, это не то же самое, что 'Classname.init()' –

2

Для некоторого заданного типа (например, UINavigationController), нет никакой разницы между обработкой вызовов к UINavigationController() или UINavigationController.init(), но последний синтаксис может (без () вызова) будет полезен при обращении к инициализатору какого-либо типа, скажем, Foo, в условиях, когда мы хотим использовать закрытие (или ссылки на закрытие), который должен иметь

  • ноля или более аргументов, и
  • типа возвращаемого Foo,

например, (Int, Double) -> Foo. В этих контекстах использование синтаксиса Foo.init может оказаться полезным: вместо того, чтобы явно разрешать замыкание повторно , вызовите известный инициализатор (связывая аргументы замыкания с инициализатором), мы можем использовать (ссылку на) инициализатор прямо как замыкание вместо , Если в аргументе инициализаторов Foo нет двусмысленности, ссылка на Foo.init в определенном контексте типа замыкания будет разрешена с использованием вывода типа правильному инициализатору.

Например, рассмотрим следующий пример

struct Foo { 
    let foo: Int 

    // (Int) -> Foo 
    init(foo: Int) { 
     self.foo = 2*foo 
    } 

    // (Int, Int) -> Foo 
    init(foo: Int, bar: Int) { 
     self.foo = foo + bar 
    } 

    //() -> Foo 
    init() { 
     self.foo = 42 
    } 
} 

let arr = [1, 2, 3] 
let fooArr1 = arr.map { Foo(foo: $0) } 
let fooArr2 = arr.map(Foo.init) 
       /* map operation expects a single argument of type (Int) -> Foo, 
        which we generally supply as a trailing closure. In this context, 
        Swift can, without ambiguity (since we have none, is this example), 
        find the correct overload among the initializers of Foo */ 
print(fooArr1.map { $0.foo }, fooArr2.map { $0.foo }) // [2, 4, 6] [2, 4, 6] 

let emptyTupArr = [(),(),()] 
let fooArr3 = emptyTupArr.map(Foo.init) // inferred to be the '() -> Foo' initializer 
print(fooArr3.map { $0.foo }) // [42, 42, 42] 
Смежные вопросы