생성자의 파라미터의 이름 또는 개수가 달라지면 여러 개의 생성자 작성이 가능하다.
class User {
var name:String
var age:Int
init(name:String, age:Int){
self.name = name
self.age = age
}
init(name2:String, age2:Int){
self.name = name2
self.age = age2
}
init(age:Int){
self.name = "albert"
self.age = age
print("init called")
}
deinit{
print("deinit user")
}
}
var user = User(name: "gu", age: 23) // 매개변수로 전달
var user2 = User(age: 24)
user2.name
user2.age
생성자가 있으면 당연히 소멸자가 있어야 했다 😂
deinitializer는 인스턴스가 메모리에서 해제되기 직전에 실행되며, 클래스의 인스턴스에만 구현 가능하다.
var user3:User? = User(age: 23)
user3 = nil // deinit user 출력
user3 = User(age:88) // init called 출력
스위프트는 인스턴스가 더 이상 필요하지 않으면 자동으로 메모리에서 소멸시킨다. user3에 nil을 넣으면 인스턴스가 더 이상 필요하지 않다고 판단하여 deinit을 호출한다.
deinitializer는 인스턴스 할당 해제 전에 자동으로 호출되며, 수동으로 호출할 수 없다.
deinitializer가 호출될 때까지 인스턴스의 할당 해제는 불가능하기에, 인스턴스의 모든 속성에 접근할 수 있으며, 이들 속성을 가지고 변경 작업을 호출할 수 있다 (가령 파일이 닫힐 때 파일 이름을 찾는 동작). 참고
구조체, 클래스에서만 사용.
인스턴스의 변수 또는 상수를 의미한다.
struct Cat {
var name:String
let gender:String // 이들을 저장 프로퍼티라고 함
}
var cat = Cat(name: "hoho", gender: "female")
print(cat)
cat.name = "kaka" // 가능.
// cat.gender = "male" // 불가. 상수이므로 값 변경 불가
let cat2 = Cat(name: "yaya", gender: "female")
// cat2.name = "yoon" // name이 변수여도 구조체 인스턴스가 상수로 선언되어 변경 불가함.
구조체는 value 타입이기에 상수로 인스턴스를 선언하게 되면 프로퍼티를 변수로 선언해도 변경 안 됨
class Lion {
var name:String
let gender:String
init(name:String, gender:String){
self.name = name
self.gender = gender
}
}
let Lion1 = Lion(name: "brian", gender: "female")
Lion1.name = "gugu" // 가능.
print(Lion1.name) // 변경됨.
클래스는 참조타입이기에 인스턴스를 상수로 선언해도 프로퍼티의 값 변경이 가능
클래스, 구조체, 열거형에서 사용 가능.
값을 저장하는 것이 아니라, 특정 연산을 수행하는 결과값을 의미.
getter, setter를 사용하여 다른 property와 값들을 직접 접근이 가능하다.
set 없이 get만 쓸 경우 읽기 전용 프로퍼티이므로 값 변경이 불가하다.
set에 매개변수 이름을 설정 안 할 경우 default 값인 newValue로 지정된다.
struct Stock{
var averagePrice: Int
var quantity: Int
var purchasePrice:Int {
get {
return averagePrice*quantity
}
set(newPrice){ // purchaseprice 변경시
averagePrice = newPrice / quantity
}
}
}
var stock = Stock(averagePrice: 2000, quantity: 6)
print(stock)
stock.purchasePrice // get 안의 코드블럭이 실행됨
stock.purchasePrice = 3000 // 변경 시 set 안 코드블럭이 실행됨
stock.averagePrice
프로퍼티 값의 변화를 관찰하고 반응한다.
새로운 값이 기존 값과 같아도 호출된다. = set 될때마다 호출
세 가지 경우에만 사용 가능.
1. 저장 프로퍼티
2, 3. 오버라이딩된 저장, 연산 프로퍼티
class Account{
var credit:Int = 0 {
willSet {//값이 저장되기 직전에 실행. 새로 저장된 프로퍼티값이 상수 매개변수로 지정. 지정 않으면 기본값은 newValue
print("잔액이 \(credit)에서 \(newValue)로 변경될 예정입니다.")
}
didSet { // 값이 지정된 직후에 실행. 기존값이 상수 매개변수로 지정. 지정하지 않으면 디폴트는 oldValue이 매개변수 이름이 됨
print("잔액이 \(oldValue)에서 \(credit)으로 변경되었습니다")
}
}
}
var account = Account()
account.credit = 1000
결과:
잔액이 0에서 1000로 변경될 예정입니다.
잔액이 0에서 1000으로 변경되었습니다.
특정 인스턴스에서 사용되는 게 아닌, 특정 타입에서 사용되는 프로퍼티
인스턴스 생성 없이 객체 내 프로퍼티에 접근 가능
따라서 변수에 클래스를 할당해 인스턴스 생성 않고도 프로퍼티 사용 가능하다. static을 사용해 선언한다.
모든 타입이 공통적인 값을 정의하는데 유용하다.
struct SomeStructure {
static var storedTypeProperty = "some value" // 저장 타입 프로퍼티
static var computedTypeProperty: Int { // 연산 타입 프로퍼티
return 1
}
}
SomeStructure.computedTypeProperty // 타입 이름을 통해서만 접근 가능
SomeStructure.storedTypeProperty
SomeStructure.storedTypeProperty = "hello"
SomeStructure.storedTypeProperty
타입 프로퍼티는 최초 호출시에 메모리에 한번 올라가고 그 후엔 어디서든 해당 프로퍼티를 공유한다. = 인스턴스 생성과 무관하다. = initializer와 상관이 없다. = 초기값이 없을 경우 초기값 세팅할 방법이 없기에 반드시 초기값이 주어져야 한다.
기존 속성이 lazy이기에 지금 예시에선 someStructure.computedTypeProperty를 호출했을 때에야 비로소 메모리에 올라간다.
연산 타입 프로퍼티는 subclass에서 오버라이딩 가능함. 참고한 자료
class Human {
class var alias: String {
return "Human Type Property"
}
}
class Sodeul: Human {
override class var alias: String {
return "Sodeul Type Property"
}
}
Human.alias // "Human Type Property"
Sodeul.alias // "Sodeul Type Property"
위와 같이 class를 선언한 연산 프로퍼티는 static 선언과 마찬가지로 연산 타입 프로퍼티이다.
하지만 subclass에서 위처럼 연산 타입 프로퍼티를 오버라이딩해서 사용이 가능하다.
class Human {
static var alias: String {
return "Human Type Property"
}
}
class Sodeul: Human {
override static var alias: String { // error! Cannot override static property
return "Sodeul Type Property"
}
}
static으로 선언할 경우 오버라이딩이 불가능하다.
is
) 클래스의 인스턴스를 부모 혹은 자식 클래스 타입으로 사용할 수 있는지 확인하는 용도(as
)로 사용한다.class TempClass {
var count:Int = 0
}
class TempStruct {
var count:Int = 0
}
// - 클래스
var class1 = TempClass()
var class2 = class1
var class3 = class1
class3.count = 2
class1.count // 2임. 변수를 복사하더라도 하나의 주소값을 가리키기에
// - 구조체
var struct1 = TempStruct()
var struct2 = struct1
var struct3 = struct2
struct2.count = 3
struct3.count = 4
struct1.count // 0
struct2.count // 3
struct3.count // 4. 값 타입이기에 같은 구조체 인스턴스를 할당하면 매번 새로운 메모리가 할당되기에