
기본
⎮ 비동기 프로그래밍(Asynchronous Programming)
- 비동기 프로그래밍 : 작업을 동시에 실행하거나, 완료 여부를 기다리지 않고 다음 작업을 수행할 수 있는 프로그래밍 방식
* iOS에서는 주로 GCD(Grand Central Dispatch)와 비동기 메서드를 사용
- 동기 / 비동기
동기(Synchronous) : 작업이 완료될 때까지 대기
비동기(Asynchronous) : 작업 완료를 기다리지 않고 바로 다음 작업 실행
- GCD(Grand Central Dispatch)의 주요 큐 :
Main Queue(모든 UI작업 처리)
Global Queue(BackGround 작업 처리 - 데이터 처리나 네트워트 요청 같은 시간이 오래 걸리는 작업)
Custom Queue(사용자 정의 작업 처리 - 큐의 우선순위를 설정하거나 병렬로 처리하고자 할 때)
DispatchQueue.global().async {
print("비동기 작업 실행")
DispatchQueue.main.async {
print("UI 업데이트")
}
}
⎮ 제네릭(Generic)
- 제네릭 : 코드의 유연성과 재사용성을 높이기 위해, 타입에 의존하지 않는 코드를 작성하는 방법
* 같은 로직을 다양한 타입에서 사용할 수 있도록 함
- 제네릭 함수 : 하나의 함수로 여러 타입을 처리
func swapValues<T>(_ a: inout T, _ b: inout T) {
let temp = a
a = b
b = temp
}
var x = 10
var y = 20
swapValue(&x, &y)
print(x) // 20
print(y) // 10
- 제네릭 타입 : 구조체, 클래스, 열거형에서 제네릭 활용 가능
// 스택에서 제네릭을 활용한 예
struct Stack<T> {
private var elements: [T] = []
mutating func push(_ element: T) {
elements.append(element)
}
mutating func pop() -> T? {
return elements.popLast()
}
}
실습
⎮ 비동기 데이터 처리하기
DispatchQueue.global()을 사용하여 백그라운드에서 숫자를 1부터 5까지 출력한 후, Main Queue 에서 "UI 업데이트 완료"를
출력하세요.
DispatchQueue.global().async {
for i in 1 ... 5 {
print(i)
}
DispatchQueue.main.async {
print("UI 업데이트 완료")
}
}
⎮ 비동기 네트워크 시뮬레이션
DispatchQueue를 사용해 다음을 구현하세요.
- 3초간 데이터를 로드하는 작업을 비동기로 수행.
- 작업 완료 후, "데이터 로드 완료" 메시지를 메인 큐에서 출력.
DispatchQueue.global().async {
for i in 1 ... 3 {
sleep(3)
}
DispatchQueue.main.async {
print("데이터 로드 완료")
}
}
⎮ 제네릭 함수 작성하기
두 값을 교환하는 제네릭 함수 swapValues<T> 를 작성하세요.
// 매개변수에 inout을 작성해줌으로써 값 변경이 가능해짐
func swapValues<T>(_ a: inout T, _ b: inout T) {
let temp = a
a = b
b = temp
}
var a = 10
var b = 20
swapValues(&a, &b)
print(a, b)
// 20, 10
⎮ 제네릭 스택 구현하기
Stack<T> 구조체를 작성하고 다음 기능을 구현하세요:
- push(_:): 스택에 요소 추가.
- pop(): 스택에서 요소 제거.
- 스택의 현재 상태를 출력하는 메서드.
struct Stack<T> {
var elements: [T] = []
mutating func push(_ element: T) {
elements.append(element)
}
mutating func pop() -> T? {
elements.isEmpty ? nil : elements.popLast()
}
}
var intStack = Stack<Int>()
intStack.push(1)
intStack.push(2)
if let poppedItem = intStack.pop() {
print(poppedItem)
}
// 2
⎮ * 매개변수에서의 inout
원래 매개변수로 받는 값은 변경할 수 없지만, inout을 포함해주면 값을 변경할 수 있음.
// 원래 함수의 형태
func sayName(_ name: String){
print("Hello, I'm \(name)")
}
sayName("uddt")
// Hello, I'm uddt
// 원래 매개변수로 받는 값은 변경할 수 없음 (Cannot assign to value: 'name' is a 'let' constant)
func sayHi(_ name: String){
name = "new" + name
print("Hello, I'm \(name)")
}
// 위 코드는 실행 불가
// inout을 포함해주면, 값을 변경할 수 있음
func sayHi(_ name: inout String){
name = "new" + name
print("Hello, I'm \(name)")
}
// sayHi("uddt") 이것처럼 바로 실행해줄 수는 없고, 변수에 값을 담고 넣어줘야함
var name = "uddt"
sayHi(&name)
// Hello, I'm newuddt
'스파르타코딩 클럽 > 사전 캠프' 카테고리의 다른 글
| 15. 스파르타 코딩클럽 [사전캠프 - Combine] (0) | 2025.02.25 |
|---|---|
| 13. 스파르타 코딩클럽 [사전캠프 - 클로저 / 객체지향 프로그래밍] (0) | 2025.02.19 |
| 12. 스파르타 코딩클럽 [사전캠프 - 자료구조/메모리 구조 및 ARC] (0) | 2025.02.09 |
| 11. 스파르타 코딩클럽 [사전캠프 - Struct와 Class/Protocol] (1) | 2025.02.08 |
| 10. 스파르타 코딩클럽 [사전캠프 - 가위바위보 게임 만들기] (1) | 2025.02.07 |