Инициализаторы

Последнее обновление: 01.01.2018

Инициализация представляет процесс подготовки объекта класса, структуры или перечисления к использованию. Этот процесс может включать установку начальных значений для свойств класса.

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

class User {
    
	var age: Int = 0
	var name: String = ""
}

var tom: User = User()

Выражение User() преставляет вызов инициализатора.

Важно, что хранимые свойства класса (то есть переменные и константы) должны быть инициализированы и иметь определенное значение ко времени создания объекта класса. В данном случае свойствам класса name и age напрямую присваиваются значения. Но также для инициализации свойств может использоваться инициализатор.

Для переопределения инициализатора в классе нам надо использовать ключевое слово init:

class User {
    
	var age: Int
	var name: String
	
	init(){
		
		age = 22
		name = "Tom"
	}
	
	func getUserInfo(){
	
		print("Имя: \(name); возраст: \(age)")
	}
}

var tom: User = User()
tom.getUserInfo()	// Имя: Tom; возраст: 22

Стоит отметить, что так как переменным name и age не присваиваются начальные значения, а их инициализация производится в инициализаторе, то можно определить эти переменные как константы:

class User {
    
    let age: Int
    let name: String
    
    init(){
        
        age = 22
        name = "Tom"
    }
}

Фактически инициализатор представляет функцию, которая выполняет начальную инициализацию объекта.

При необходимости мы можем определять дополнительные инициализаторы:

class User {
    
	var age: Int
	var name: String
	
	init(){
		
		age = 22
		name = "Tom"
	}
	init(name: String, age: Int){
		
		self.age = age
		self.name = name
	}
	
	func getUserInfo(){
	
		print("Имя: \(self.name); возраст: \(self.age)")
	}
}

var bob: User = User(name: "Bob", age: 34)
bob.getUserInfo()	// Имя: Bob; возраст: 34

Второй инициализатор принимает два параметра name и age для установки свойств класса. Так как параметры и свойства класса называются одинаково, то для их разграничения вместе с названиями свойств используется ключевое слово self.

И при создании объекта в данном случае используется второй инициализатор: var bob: User = User(name: "Bob", age: 34)

Инициализаторы могут определять значения по умолчанию для параметров. Так, пример выше мы могли бы сократить следующим образом:

class User {
    
    var age: Int
    var name: String
    
    init(name: String = "Tom", age: Int = 22){
        
        self.age = age
        self.name = name
    }
    
    func getUserInfo(){
        
        print("Имя: \(self.name); возраст: \(self.age)")
    }
}
var tom = User()
tom.getUserInfo()	// Имя: Tom; возраст: 22

Делегирование инициализации

Одни инициализаторы могут вызывать другие. Вызывающие инициализаторы должны быть определены с ключевым словом convenience:

class User {
    
	var age: Int
	var name: String
	
	convenience init(){
		
		self.init(name: "Tom", age: 22)
	}
	init(name: String, age: Int){
		
		self.age = age
		self.name = name
	}
	
	func getUserInfo(){
	
		print("Имя: \(self.name); возраст: \(self.age)")
	}
}

var tom: User = User()
tom.getUserInfo()	// Имя: Tom; возраст: 22

Failable-инициализаторы

Специальная разновидность инициализаторов (Failable Initializer) позволяет возвратить значение nil, если в процессе инициализации объекта произошла какая-нибудь ошибка. Например:

class User{
	
	var name: String
	var age: Int
	init?(name: String, age: Int){
		
		self.name = name
		self.age = age
		if(age < 0){
			return nil
		}
	}
}
var bob: User = User(name: "Bob", age: 34)!
print(bob.name)	// Bob

Поскольку пользователь, представленный классом User, в принципе не может иметь возраст меньше нуля. Поэтому ситуация, когда для возраста передается число меньше нуля, может рассматриваться как ошибочная. И в этом случае мы как раз можем использовать failable-инициализатор.

Для определения такого инициализатора после слова init ставится знак вопроса, а в самом инициализаторе можно предусмотреть ситуацию, при которой он возвращает значение nil:

init?(name: String, age: Int){
		
	self.name = name
	self.age = age
	if(age < 0){
		return nil
	}
}

Возвращая nil, мы тем самым указываем, что мы не можем создать объект User по тем данным, которые переданы в инициализатор.

Важно учитывать, что объект, создаваемый этим инициализатором, будет представлять не тип User, а тип User?. Поэтому для получения значения нам надо еще использовать операцию ! (восклицательный знак):

var bob: User = User(name: "Bob", age: 34)!

Либо мы можем напрямую работать с объектом User?:

var bob: User? = User(name: "Bob", age: 34)

Однако надо учитывать, что если мы передадим неправильные данные, то инициализатор возвратит nil, и получение значение окончится ошибкой. Поэтому в таких случаях перед использованием объекта мы можем проверять на наличие значения:

if let lora = User(name: "Lora Palmer", age: -4){
	print(lora.name)
}
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850