스위프트는 함수형 프로그래밍 패러다임을 강조하지만 못지않게 객체지향 프로그래밍 패러다임도 매우 중요합니다.
애플의 프레임워크는 대부분 객체지향 프로그래밍 패러다임에 근간을 두기에 스위프트에서 객체지향 프로그래밍 패러다임을 배제하기는 어려웠을 것입니다.
struct
키워드를 사용함struct BasicInformation {
var name: Stirng
var age: Int
}
(.)
를 사용하면 됨// 프로퍼티 이름(name, age)으로 자동 생성된 이니셜라이저를 사용하여 구조체를 생성합니다.
var tomaInfo: BasicInformation = BasicInformation(name: "toma", age: 2)
tomaInfo.age = 100
tomaInfo.name = "mato"
let tomaInfo: BasicInformation = BasicInformation(name: "toma", age: 2)
tomaInfo.age = 20 // error
tomaInfo.name = "mato" // error
class
키워드를 사용함class Person {
var height: Float = 0.0
var weight: Float = 0.0
}
var toma: Person = Person()
toma.height = 190
toma.weight = 40
let mato: Person = Person()
mato.height = 190
toma.weight = 40
소멸
이라고 함deinit(디이니셜라이저)
이라는 메서드가 호출됨 (클래스 내부에 구현 가능)deinit
은 클래스당 하나만 구현할 수 있으며, 매개변수와 반환값을 가질 수 없음class Person {
var height: Float = 0.0
var weight: Float = 0.0
deinit {
print("Person 클래스의 인스턴스가 소멸됩니다")
}
}
var yagom: Person? = Person()
yagom = nil // Person 클래스의 인스턴스가 소멸됩니다"
가장 큰 차이 점은 값 타입과 참조 타입이라는 것입니다.
무엇이 전달되느냐
임복사
되어 전달참조(주소)
가 전달*
를 사용하지는 않음참조(주소)
가 할당됨struct BasicInformation {
let name: String
var age: Int
}
var tomaInfo: BasicInformation = BasicInformation(name: "toma", age: 200)
tomaInfo.age = 20
// tomaInfo 값을 복사하여 friendInfo에 할당!
var friendInfo: BasicInformation = tomaInfo
print("toma's age: \(tomaInfo.age)") // 20
print("friend's age: \(friendInfo.age)") // 20
friendInfo.age = 999
print("toma's age: \(tomaInfo.age)") // 20
print("friend's age: \(friendInfo.age)") // 999
// tomaInfo의 값을 복사했기 때문에 별개의 값을 가짐
func changeBasicInfo(_ info: BasicInformation){
var copiedInfo: BasicInformation = info
copiedInfo.age = 1
}
changeBasicInfo(tomaInfo)
print("toma's age: \(tomaInfo.age)") // 20
//call by value 이기 때문에 따로 값이 변경되지 않음
class Person {
var height: Float = 0.0
var weight: Float = 0.0
}
var toma: Person = Person()
var friend: Person = toma // toma의 참조를 할당
print("toma's height: \(toma.height)") // 0.0
print("friend's height: \(friend.height)") // 0.0
friend.height = 185.5
print("toma's height: \(toma.height)") // 185.5
// friend는 toma를 참조하기 때문에 값이 같이 변함
print("friend는's height: \(friend.height)") // 185.5
func changePersonInfo(_ info: Person){
info.height = 155.3
}
changePersonInfo(toma)
print("yagom height: \(toma.height)") // 155.3
//Call by reference 이기 때문에 실제 값이 변화되어 155.3 출력
클래스의 인스턴스끼리 참조가 같은지 확인할 때는 식별 연산자를 사용
var toma: Person = Person()
let friend: Person = toma
let anotherFriend: Person = Person()
print(toma === friend) // true
print(toma === anotherFriend) // false
print(friend !== anotherFriend) // true
스위프트의 기본 데이터 타입이 모두 구조체이기 때문에 모든 데이터 타입의 값을 복사하고 이용할 때 메모리를 비효율적으로 사용한다고 오해할 수 있다.
하지만 스위프트는 꼭 필요한 경우에만 진짜 복사를 한다.
컴파일러의 판단으로 복사가 필요없을 경우, 요소가 많은 큰 배열을 함수의 전달인자를 넘겨준다고 해서 꼭 모든 값을 메모리의 다른 공간에 복사해서 넣지 않을 수도 있다.