- A 라는 클래스가 있을 때, 앱 전체에서 특정 용도로 하나의 인스턴스만 생성해서 공용으로 사용하고 싶을때 사용하는 디자인 유형
클래스 , 구조체 , 열거형에서 사용된다.
저장 타입 프로퍼티, 연산 타입 프로퍼티가 있다.
class Human { static let name: String = "ksw" // 저장 타입 프로퍼티 static var alias: String { // 연산 타입 프로퍼티 return name + "hello" } }
static 을 사용하면 오버라이딩 불가능, class 를 사용하면 오버라이딩이 가능하다.
타입 프로퍼티는 인스턴스가 생성될 때마다 "매번 생성"되는 "기존 프로퍼티"와 다르다.
인스턴스가 생성된다고 매번 해당 인스턴스의 멤버로 매번 생성되는 것이 아니라, 언제 누가 한번 불러서 메모리에 올라가면 그 뒤로는 생성되지 않고, 언제 어디서든 이 타입 프로퍼티에 접근할 수 있게 된다.
- 타입 프로퍼티를 사용해서 싱글톤을 만들면 이렇게 만들 수 있다.
class MyClass { static let shared = MyClass() var someValue: Int? }
shared 는 타입 프로퍼티이기 때문에 단 한번만 생성되고 그 뒤로는 참조가 된다. -> Singleton
사용은 다음과 같이 할 수 있다.
-> AViewController.swift
let myClass = MyClass.shared myClass.someValue = 100
-> BViewController.swift
let myClass = MyClass.shared print(myClass.someValue) // 100
개발하고 있는 앱에서 다음과 같이 뒤로가기 버튼을 공통적으로 사용할 일이 많아서 다음과 같은 클래스를 정의했었다. 각각 AViewController.swift, BViewController.swift 의 모습이다.
플로우 : Home -> A -> B
즉 B에서 뒤로가기를 누르면 화면 A가, A에서 뒤로가기를 누르면 Home 이 나와야한다.
// Fooiy 라는 앱에서 사용할 버튼들 class FooiyButtons { // 타입 프로퍼티 static let backButton: UIButton = { let button = UIButton() let image = UIImage(named: "Icon_arrow") button.setImage(image, for: .normal) return button }() }
그래서 위와 같이 FooiyButtons 안에 타입 프로퍼티로 backButton 을 정의하고 AViewController.swift 와 BViewController.swift 에서 이렇게 사용했다.
- A.ViewController.swift
// FooiyButtons 클래스의 타입 프로퍼티를 가져온다. let backButton = FooiyButtons.backButton // 클릭하면 pop ViewController backButton.rx.tap.bind{ [weak self] in guard let self = self else { return } self.navigationController?.popViewController(animated: true) print("log1") }.disposed(by: disposeBag)
- B.ViewController.swift
// FooiyButtons 클래스의 타입 프로퍼티를 가져온다. let backButton = FooiyButtons.backButton // 클릭하면 pop ViewController backButton.rx.tap.bind{ [weak self] in guard let self = self else { return } self.navigationController?.popViewController(animated: true) print("log2") }.disposed(by: disposeBag)
즉, 같은 코드를 서로 다른 곳에 2번 작성했다.
그런데 B에서 뒤로가기 버튼을 한 번 눌렀을때, A로 돌아가는 것이 아니라, Home 까지 2번 뒤로가게 되는 현상이 발생했다.
왜냐하면 A에서 이미 FooiyButtons 의 backButton 을 선언했는데, B에서 새롭게 FooiyButtons.backButton 을 선언한다고 해서 별개의 버튼이 생성되는 것이 아니기 때문이었다.
다시 말하면, 타입 프로퍼티는 메모리에 한번 올라가면 그 뒤로는 생성되지 않고, 다른 곳에서 그 타입 프로퍼티에 접근하기 때문 !
B에서 backButton 을 누르면 BViewController.swift 의 popViewController 도 실행이 되고, AViewController.swift 의 popViewController 도 실행이 되기 때문에 2번 뒤로가게 되는 현상이 발생하게 되는 거였다.