No.17
타입 메서드
- 메서드이지만, 인스턴스의 성격이 아닌 타입 자체의 성격에 가까운 메서드
- 메서드이기 때문에 메모리 공간 할당 X
- 인스턴스에 대한 속성이 아니고 타입자체에 대한 속성.
- 내/외부에서 Type.method()로 접근
- 메서드 실행시, (따로) 스택프레임을 만들고 타입 데이터를 사용 → 종료시 스택프레임
- 타입에 해당하는 보편적인 동작의 경우
- Int.random(in: 1…100)
class Dog {
static var species = "Dog"
init(name: String, weight: Double) {
self.name = name
self.weight = weight
}
static func letmeKnow() { // 타입 메서드에서, 타입속성에 접근시에는 타입으로 접근하지 않아도 됨
print("종은 항상 \(species)입니다.") // Dog.species라고 써도됨
}
}
// 타입 메서드의 호출 ⭐️
Dog.letmeKnow()
- 클래스 - 타입 메서드의 상속
- 타입 메서드를 상속시 재정의가능 하도록 하려면, static 키워드를 상속가능한 class 키워드로 바꿔야 함
class SomeClass {
class func someTypeMethod() {
//
}
}
// 상속시
class SomeThingClass: SomeClass {
override class func someTypeMethod() {
//
}
}
서브스크립트
- 대괄호는 사실, 특별한 형태의 메서드(기능) 호출 역할
- → 메서드를 직접 구현도 가능
- 함수의 구현이 특별한 키워드인 subscript로 명명됨
- 메서드이기 때문에 인스턴스에 메모리 공간 할당 X
- 인스턴스 이름으로 접근해야 함 → instance[파라미터] // unique 형태
- 메서드 실행시, 스택프레임을 만들고 필요한 데이터를 사용
- 메서드 종료시 스택프레임 사라짐
- 파라미터 2개이상도 구현가능(아규먼트 레이블 사용 x)
- get블록만 선언시 읽기전용 계산 속성(필수 구현)
- set은 선택적으로 구현
- newValue 기본 파라미터 제공
- 타입 서브스크립트
- 서브스크립트 메서드 앞에 static, class 키워드만 붙이면 가능
class SomeData {
var datas = ["Apple", "Swift", "iOS", "Hello"]
subscript(idx: Int) -> String { // 1) 함수와 동일한 형태이지만, 이름은 subscript
get { // 2) get/set은 계산속성에서의 형태와 비슷
return datas[idx]
}
set {
datas[idx] = newValue // 또는 파라미터 생략하고 newValue로 대체 가능(계산 속성의 setter와 동일)
}
}
}
var data = SomeData()
data[0] = "Google"
data[0] // Google
- 사용 예시
- 대괄호 형태로 사용하는 메서드
// Document E.g
struct TimesTable {
let multiplier: Int
subscript(index: Int) -> Int {
return multiplier * index
}
}
let threeTimesTable = TimesTable(multiplier: 3)
print("six times three is \(threeTimesTable[6])")
// Prints "six times three is 18"
- 타입 서브스크립트(Type Subscripts) - 클래스, 구조체, 열거형
enum Planet: Int { // 열거형의 원시값
case mercury = 1, venus, earth, mars, jupiter, saturn, uranus, neptune
static subscript(n: Int) -> Planet { // Self
return Planet(rawValue: n)!
}
}
let mars = Planet[2] // venus
print(mars)
- Int/String 등의 타입 이해
- 실제, 구조체로 구현 되어있음
- Int는 구조체로 구현이 되어있고, 타입 메서드 형태로 랜덤하수가 구현이 되어있었기 때문에 위와 같은 방식으로 사용할 수 있던 것
struct Int {
...
static func random(in range: Range<Int>) -> Int {...}
...
}
// Int.random(in: 1...100)
접근제어(Access Control)
- private으로 선언된 속성, 메서드에 접근불가
- 코드 내부의 세부 구현 내용을 숨기는 것이 가능 == 은닉화
- 왜 필요한가?
- 자신들이 원하는 코드를 감출 수 있음
- 코드의 영역을 분리시켜서, 효율적 관리 가능
- 컴파일 시간이 줄어듬 (컴파일러가, 해당 변수가 어느범위에서만 쓰이는지를 인지 가능)
싱글톤(Singleton)
- 앱 구현시에, 유일하게 한개만 존재하는 객체가 필요한 경우에 사용
- 특정한 유일한 데이터/관리 객체가 필요한 경우
- 메모리 절약을 위해, 인스턴스가 필요할 때 똑같은 인스턴스를 새로 만들지 않고 기존의 인스턴스를 가져와 활용하는 기법
- 전역 변수를 사용하는 이유와 비슷한 맥락이다.
- 보통 싱글톤 패턴이 적용된 객체가 필요한 경우는 그 객체가 리소스를 많이 차지하는 역할을 하는 무거운 클래스일때 적합하다.
- 한번 생성된 이후에는 앱이 종료될때까지, 유일한 객체로 메모리에 상주
- 붕어빵 틀에 객체주소(자기자신)을 넣어둠, 객체가 메모리 공간에서 해제되기 전까지 사용(접근) 가능
- 하나의 객체(데이터 영역에 유일한 객체의 주소가 담겨있음)
- Singleton.shared 는 어디서 선언되어도 동일한 객체를 가짐.
- 한번 생성이 되면, 앱이 종료할때까지 1개의 객체로써 메모리(힙)에 상주
- 변수로 접근하는 순간 lazy하게 동작, 메모리(데이터 영역)에 올라감

- 문법적 이해
class Singleton {
// 타입 프로퍼티(전역변수)로 선언
static let shared = Singleton() // 자신의 객체를 생성해서 전역변수에 할당
var userInfoId = 12345
private init() {} // private init() 설정으로 새로운 객체 추가적 생성이 불가하게 막는 것 가능
}
- 실제 사용 예시
- 고정된 메모리 영역을 가지고 하나의 인스턴스만 사용하기 때문에 메모리 낭비를 방지할 수 있다.
- DataBase connection Pool 처럼 공통된 객체를 여러개 생성해야 하는 상황에서 많이 사용된다.
// 앱을 실행하는 동안, 하나의 유일한 객체만 생성되어서, 해당 부분을 관리
// 실제 아래 예시들이 모두 Singleton 패턴
let screen = UIScreen.main // 화면
let userDefaults = UserDefaults.standard // 한번생성된 후, 계속 메모리에 남음!!!
let application = UIApplication.shared // 앱
let fileManager = FileManager.default // 파일
let notification = NotificationCenter.default // 노티피케이션(특정 상황, 시점을 알려줌)
반응형
'iOS > Swift' 카테고리의 다른 글
Swift No.17 (1) | 2024.01.23 |
---|---|
Swift No.16 (0) | 2024.01.17 |
Swift No.14 (0) | 2024.01.16 |
Swift No.13 (0) | 2024.01.14 |
Swift No.12 (0) | 2024.01.13 |
No.17
타입 메서드
- 메서드이지만, 인스턴스의 성격이 아닌 타입 자체의 성격에 가까운 메서드
- 메서드이기 때문에 메모리 공간 할당 X
- 인스턴스에 대한 속성이 아니고 타입자체에 대한 속성.
- 내/외부에서 Type.method()로 접근
- 메서드 실행시, (따로) 스택프레임을 만들고 타입 데이터를 사용 → 종료시 스택프레임
- 타입에 해당하는 보편적인 동작의 경우
- Int.random(in: 1…100)
class Dog {
static var species = "Dog"
init(name: String, weight: Double) {
self.name = name
self.weight = weight
}
static func letmeKnow() { // 타입 메서드에서, 타입속성에 접근시에는 타입으로 접근하지 않아도 됨
print("종은 항상 \(species)입니다.") // Dog.species라고 써도됨
}
}
// 타입 메서드의 호출 ⭐️
Dog.letmeKnow()
- 클래스 - 타입 메서드의 상속
- 타입 메서드를 상속시 재정의가능 하도록 하려면, static 키워드를 상속가능한 class 키워드로 바꿔야 함
class SomeClass {
class func someTypeMethod() {
//
}
}
// 상속시
class SomeThingClass: SomeClass {
override class func someTypeMethod() {
//
}
}
서브스크립트
- 대괄호는 사실, 특별한 형태의 메서드(기능) 호출 역할
- → 메서드를 직접 구현도 가능
- 함수의 구현이 특별한 키워드인 subscript로 명명됨
- 메서드이기 때문에 인스턴스에 메모리 공간 할당 X
- 인스턴스 이름으로 접근해야 함 → instance[파라미터] // unique 형태
- 메서드 실행시, 스택프레임을 만들고 필요한 데이터를 사용
- 메서드 종료시 스택프레임 사라짐
- 파라미터 2개이상도 구현가능(아규먼트 레이블 사용 x)
- get블록만 선언시 읽기전용 계산 속성(필수 구현)
- set은 선택적으로 구현
- newValue 기본 파라미터 제공
- 타입 서브스크립트
- 서브스크립트 메서드 앞에 static, class 키워드만 붙이면 가능
class SomeData {
var datas = ["Apple", "Swift", "iOS", "Hello"]
subscript(idx: Int) -> String { // 1) 함수와 동일한 형태이지만, 이름은 subscript
get { // 2) get/set은 계산속성에서의 형태와 비슷
return datas[idx]
}
set {
datas[idx] = newValue // 또는 파라미터 생략하고 newValue로 대체 가능(계산 속성의 setter와 동일)
}
}
}
var data = SomeData()
data[0] = "Google"
data[0] // Google
- 사용 예시
- 대괄호 형태로 사용하는 메서드
// Document E.g
struct TimesTable {
let multiplier: Int
subscript(index: Int) -> Int {
return multiplier * index
}
}
let threeTimesTable = TimesTable(multiplier: 3)
print("six times three is \(threeTimesTable[6])")
// Prints "six times three is 18"
- 타입 서브스크립트(Type Subscripts) - 클래스, 구조체, 열거형
enum Planet: Int { // 열거형의 원시값
case mercury = 1, venus, earth, mars, jupiter, saturn, uranus, neptune
static subscript(n: Int) -> Planet { // Self
return Planet(rawValue: n)!
}
}
let mars = Planet[2] // venus
print(mars)
- Int/String 등의 타입 이해
- 실제, 구조체로 구현 되어있음
- Int는 구조체로 구현이 되어있고, 타입 메서드 형태로 랜덤하수가 구현이 되어있었기 때문에 위와 같은 방식으로 사용할 수 있던 것
struct Int {
...
static func random(in range: Range<Int>) -> Int {...}
...
}
// Int.random(in: 1...100)
접근제어(Access Control)
- private으로 선언된 속성, 메서드에 접근불가
- 코드 내부의 세부 구현 내용을 숨기는 것이 가능 == 은닉화
- 왜 필요한가?
- 자신들이 원하는 코드를 감출 수 있음
- 코드의 영역을 분리시켜서, 효율적 관리 가능
- 컴파일 시간이 줄어듬 (컴파일러가, 해당 변수가 어느범위에서만 쓰이는지를 인지 가능)
싱글톤(Singleton)
- 앱 구현시에, 유일하게 한개만 존재하는 객체가 필요한 경우에 사용
- 특정한 유일한 데이터/관리 객체가 필요한 경우
- 메모리 절약을 위해, 인스턴스가 필요할 때 똑같은 인스턴스를 새로 만들지 않고 기존의 인스턴스를 가져와 활용하는 기법
- 전역 변수를 사용하는 이유와 비슷한 맥락이다.
- 보통 싱글톤 패턴이 적용된 객체가 필요한 경우는 그 객체가 리소스를 많이 차지하는 역할을 하는 무거운 클래스일때 적합하다.
- 한번 생성된 이후에는 앱이 종료될때까지, 유일한 객체로 메모리에 상주
- 붕어빵 틀에 객체주소(자기자신)을 넣어둠, 객체가 메모리 공간에서 해제되기 전까지 사용(접근) 가능
- 하나의 객체(데이터 영역에 유일한 객체의 주소가 담겨있음)
- Singleton.shared 는 어디서 선언되어도 동일한 객체를 가짐.
- 한번 생성이 되면, 앱이 종료할때까지 1개의 객체로써 메모리(힙)에 상주
- 변수로 접근하는 순간 lazy하게 동작, 메모리(데이터 영역)에 올라감

- 문법적 이해
class Singleton {
// 타입 프로퍼티(전역변수)로 선언
static let shared = Singleton() // 자신의 객체를 생성해서 전역변수에 할당
var userInfoId = 12345
private init() {} // private init() 설정으로 새로운 객체 추가적 생성이 불가하게 막는 것 가능
}
- 실제 사용 예시
- 고정된 메모리 영역을 가지고 하나의 인스턴스만 사용하기 때문에 메모리 낭비를 방지할 수 있다.
- DataBase connection Pool 처럼 공통된 객체를 여러개 생성해야 하는 상황에서 많이 사용된다.
// 앱을 실행하는 동안, 하나의 유일한 객체만 생성되어서, 해당 부분을 관리
// 실제 아래 예시들이 모두 Singleton 패턴
let screen = UIScreen.main // 화면
let userDefaults = UserDefaults.standard // 한번생성된 후, 계속 메모리에 남음!!!
let application = UIApplication.shared // 앱
let fileManager = FileManager.default // 파일
let notification = NotificationCenter.default // 노티피케이션(특정 상황, 시점을 알려줌)
반응형
'iOS > Swift' 카테고리의 다른 글
Swift No.17 (1) | 2024.01.23 |
---|---|
Swift No.16 (0) | 2024.01.17 |
Swift No.14 (0) | 2024.01.16 |
Swift No.13 (0) | 2024.01.14 |
Swift No.12 (0) | 2024.01.13 |