Swift는 Objective-C를 대체하기 위해 WWDC 2014에서 발표된 Apple의 최신 프로그래밍 언어입니다. Swift는 타입 안전성, 자동 메모리 관리 ARC(Automatic Reference Counting) 및 프로토콜 지향 접근 방식을 결합합니다. Swift Programming Language는 언어의 구문과 표준 라이브러리에 대한 주요 정보 출처입니다.
핵심 포인트
Swift는 Apple이 iOS, macOS, watchOS, tvOS 및 visionOS를 위해 개발한 다중 패러다임 프로그래밍 언어입니다. 언어의 주요 목표는 안전성, 속도 및 구문 표현력입니다. Swift는 LLVM 컴파일러를 사용하며 C++에 필적하는 성능의 최적화된 기계어 코드를 생성합니다.
2014년 출시 이후 Swift는 6개의 주요 버전을 거쳤습니다. Swift 6(2024)은 동시 코드 격리를 엄격하게 제어하여 완전한 데이터 경합 안전성 모델을 도입했습니다. GitHub Octoverse 2025에 따르면 Swift는 커뮤니티 성장률에서 상위 10개 언어에 속하며 Apple 플랫폼에서 채택 속도에서 Rust와 Kotlin을 앞지르고 있습니다.
Swift는 오픈 소스이며 크로스 플랫폼입니다 — 소스 코드는 GitHub(Swift Open Source)에 공개되어 있습니다. Apple 플랫폼 외에도 Swift는 Linux와 Windows에서 서버 측 개발(Vapor, Hummingbird)에 사용되지만, 주요 영역은 Apple 생태계 내의 모바일 및 데스크톱 개발입니다.
전환의 주요 이유: Swift는 Objective-C에서 발생할 수 있는 오류의 전체 클래스를 제거합니다. 타입 안전성은 컴파일 타임에 타입 불일치를 방지합니다. Optionals는 nil 역참조를 제거합니다. ARC는 Objective-C의 MRC/ARC와 달리 첫날부터 내장되어 있습니다. Swift 구문은 더 짧고 읽기 쉽습니다 — 연구에 따르면 동등한 작업에 대해 Objective-C 대비 코드 양이 30-40% 감소합니다.
기본 Swift 구문은 익숙한 C 유사 구조와 함수형 언어의 요소를 결합합니다. 변수는 var로, 상수는 let으로 선언됩니다. 컴파일러는 타입 추론을 사용하므로 명시적 타입 주석은 모호한 경우에만 필요합니다.
import Foundation
// 상수와 변수
let name = "Swift"
var version = 6.0
var count: Int = 42
// 기본 매개변수가 있는 함수
func greet(person: String, greeting: String = "Hello") -> String {
return "\(greeting), \(person)!"
}
// 조기 종료를 위한 Guard-let
func parse(input: String?) -> Int {
guard let value = input, let number = Int(value) else {
return 0
}
return number
}Switch와 패턴 매칭은 Swift에서 C와 Kotlin보다 더 강력합니다. Switch는 튜플, 범위, where 조건 및 값 바인딩과의 매칭을 지원합니다. 컴파일러는 모든 케이스의 포괄적인 범위를 확인합니다 — 가능한 모든 값이 포함된 경우 default가 없어도 오류가 아닙니다.
let point = (x: 3, y: -1)
switch point {
case (0, 0):
print("원점")
case let (x, y) where x == y:
print("X는 Y와 같음")
case let (x, y) where abs(y) > x:
print("Y의 절대값이 X보다 큼")
default:
print("점 (\(point.x), \(point.y))")
}Optionals는 타입 시스템 수준에서 null 참조 문제를 해결하는 Swift의 핵심 개념입니다. Optional
var optionalString: String? = "Hello"
optionalString = nil // 허용됨
// Optional Binding — 안전한 추출
if let text = optionalString {
print("텍스트: \(text)")
} else {
print("값 없음")
}
// Optional Chaining — 속성에 대한 안전한 접근
let length = optionalString?.count ?? 0
// Nil-coalescing 연산자
let greeting = optionalString ?? "Default"Optional Chaining(?. 연산자)을 사용하면 옵셔널 값의 메서드를 안전하게 호출하고 속성에 액세스할 수 있습니다. 체인이 nil에서 중단되면 전체 표현식의 결과는 nil입니다. Nil-coalescing(??)은 기본값을 제공하며 플레이스홀더 텍스트 표시를 위한 UI 코드에서 널리 사용됩니다.
프로토콜은 Swift에서 계약(속성 및 메서드 집합)을 정의합니다. Java 인터페이스와 달리 Swift 프로토콜은 프로토콜 확장(protocol extensions)을 통해 기본 구현을 가질 수 있습니다. 이것이 클래스 상속 대신 Apple이 권장하는 접근 방식인 프로토콜 지향 프로그래밍의 기초입니다.
protocol NamedEntity {
var name: String { get }
func description() -> String
}
// 확장을 통한 기본 구현
extension NamedEntity {
func description() -> String {
return "Entity: \(name)"
}
}
// 확장을 통한 준수
extension String: NamedEntity {
var name: String { return self }
}Protocol Extensions를 사용하면 각 준수 타입을 수정하지 않고 프로토콜에 메서드를 추가할 수 있습니다. 이는 Sequence의 map, filter, reduce 또는 JSON 직렬화를 위한 Codable과 같은 공통 유틸리티를 추가하는 데 특히 유용합니다. Apple은 많은 프레임워크(SwiftUI, Combine)를 확장이 있는 프로토콜 위에 구축했습니다.
클로저는 외부 컨텍스트에서 변수를 캡처하는 익명 함수입니다. 구문적으로 클로저는 Kotlin의 람다와 유사하지만 더 유연한 구문(trailing closure, 약식 인수 이름 $0/$1, autoclosures)을 가지고 있습니다.
// 컨텍스트 캡처가 있는 클로저
let numbers = [5, 3, 8, 1, 9]
// Trailing closure syntax
let sorted = numbers.sorted { $0 < $1 }
// 함수형 체인
let result = numbers
.filter { $0 > 3 }
.map { $0 * 2 }
.reduce(0, +)
// 함수 매개변수로서의 클로저
func performAsync(completion: @escaping (Result<Data, Error>) -> Void) { }@escaping 클로저는 함수가 반환된 후 클로저가 실행될 때 사용됩니다 — 일반적으로 네트워크 요청 및 비동기 작업에 사용됩니다. @autoclosure는 표현식을 자동으로 클로저로 래핑하며 assert 및 단락 논리에서 사용됩니다.
struct와 class 중 선택은 Swift 모델을 설계할 때 첫 번째 결정 중 하나입니다. Apple은 기본적으로 struct(값 타입)를 사용하고 상속이나 참조 식별이 필요한 경우에만 class(참조 타입)로 전환할 것을 권장합니다.
| 특성 | Struct | Class |
|---|---|---|
| 전달 방식 | 값 전달(복사) | 참조 전달 |
| 상속 | 지원 안 함 | 지원함 |
| ARC 관리 | 필요 없음 | ARC(참조 카운팅) |
| 초기화 해제자 deinit | 없음 | 있음 |
| 가변성 | 속성 변경 시 mutating func 필요 | 모든 메서드가 변경 가능 |
| 컬렉션 저장 | 삽입 시 복사됨 | 참조가 저장됨 |
값 타입(struct)은 멀티스레드 환경에서 더 안전합니다 — 각 스레드가 독립적인 복사본을 얻습니다. 참조 타입(class)은 UIKit(UIView, UIViewController) 작업에 필요하며, 여기서 참조 식별과 시스템 클래스 상속이 필요합니다.
ARC(Automatic Reference Counting)는 참조 타입을 위한 Swift의 메모리 관리 시스템입니다. 컴파일러는 런타임에 retain/release 호출을 삽입하여 객체에 대한 강한 참조 수를 추적합니다. 카운터가 0에 도달하면 객체가 즉시 해제됩니다.
ARC의 주요 문제는 순환 참조(retain cycles)입니다. 두 객체가 서로에 대한 강한 참조를 보유하면 메모리가 해제되지 않습니다. 해결책은 약한 참조(weak, 해제 시 자동으로 nil이 됨)와 unowned 참조(객체가 살아있음을 보장)입니다.
class ProfileViewController: UIViewController {
var onLogout: (() -> Void)?
func setupHandler() {
// [weak self]는 순환 참조를 방지함
onLogout = { [weak self] in
guard let self else { return }
self.dismiss(animated: true)
}
}
}클로저에서 순환 참조를 방지하려면 [weak self]를 guard let self = self else { return }과 함께 사용하세요. 이 규칙은 UIKit에서 특히 중요합니다. ViewController가 자신의 속성에 대한 강한 참조를 보유하고 해당 속성 내부의 클로저가 ViewController를 참조하기 때문입니다.
자주 묻는 질문
Swift는 Int, Double, Float, String, Bool, Array, Set, Dictionary 및 튜플을 지원합니다. 숫자 타입은 고정 크기(Int8, Int16, Int32, Int64 및 부호 없는 UInt)를 가집니다. 날짜 작업에는 Foundation의 Date가 사용되고, 데이터에는 Data가 사용됩니다.
Optional은 두 가지 케이스가 있는 열거형입니다: .none(nil) 및 .some(Wrapped). Swift는 if let, guard let 또는 ??를 통한 명시적 Optional 확인을 요구하여 NullPointerException을 제거합니다. 옵셔널 체이닝(?. )을 사용하면 중첩된 옵셔널 값의 속성에 안전하게 액세스할 수 있습니다.
struct — 값 타입, 할당 시 복사되며 상속을 지원하지 않고 ARC가 필요하지 않습니다. class — 참조 타입, 참조로 전달되며 상속과 초기화 해제자를 지원합니다. Apple은 기본 타입으로 struct를 권장합니다.
ARC는 클래스 객체에 대한 강한 참조를 자동으로 카운트합니다. 카운터가 0이 되면 메모리가 해제됩니다. 순환 참조를 방지하려면 weak(자동 nil) 및 unowned(보장된 수명)를 사용하세요. ARC는 struct와 enum에는 적용되지 않습니다.
프로토콜 지향 프로그래밍은 클래스 계층 대신 확장이 있는 프로토콜을 사용하는 접근 방식입니다. 프로토콜은 프로토콜 확장을 통해 기본 메서드 구현을 가질 수 있습니다. 이를 통해 상속 없이 코드를 재사용할 수 있으며 유연성과 테스트 용이성을 유지합니다.
요약
턴키 방식의 모바일 애플리케이션을 개발해 드립니다
IT Sectr는 2017년부터 스타트업과 기업을 위한 iOS 및 Android 애플리케이션을 만듭니다. 저희가 상담해 드리고 최적의 솔루션을 제안하겠습니다.