2025/06 11

[iOS] 성능 최적화: @inlinable과 lazy

✅ @inlinable이란?@inlinable은 컴파일러에게 특정 함수나 계산 속성을 인라인 최적화할 수 있다고 알려주는 키워드인라인 최적화: 함수 호출 대신 함수의 실제 코드를 호출 지점에 직접 삽입하는 것// 일반적인 함수 호출func square(_ x: Int) -> Int { return x * x}let result = square(5) // 함수 호출 오버헤드 발생// @inlinable로 최적화된 경우@inlinablefunc square(_ x: Int) -> Int { return x * x}let result = 5 * 5 // 컴파일러가 직접 코드 삽입 ✅ @inlinable의 특징성능 향상: 함수 호출 오버헤드 제거모듈 경계 최적화: 다른 모듈에서도 인라인 최적화 가능..

iOS 2025.06.25

[iOS] Unit Test 기본 개념과 적용

✅ 단위 테스트(Unit Test)란?정의: 코드의 작은 단위(예: 함수, 메서드)가 예상대로 동작하는지 자동으로 확인하는 것// 예를 들어, 이런 함수가 있다면func add(a: Int, b: Int) -> Int { return a + b}// 테스트는 이런 식으로 검증// "add(2, 3)을 호출하면 5가 나와야 한다" ✅ 테스트의 핵심 개념1. Given-When-Then 패턴모든 테스트는 이 3단계로 구성func test_saveSummaryState_shouldSaveCorrectly() { // Given (준비): 테스트에 필요한 데이터 준비 let bookTitle = "Harry Potter" let isExpanded = true // When ..

iOS 2025.06.23

[Swift] Singleton에서의 private init()

✅ private init()의 역할private initializer는 코드의 다른 부분에서 Settings 클래스 인스턴스를 생성하려고 시도하는 것을 막아줌class MySingleton { static let shared = MySingleton() private init() {} // 👈👈} class UserDefaultsManager { static let shared = UserDefaultsManager() private init() {} // 외부 생성 차단}// 다른 곳에서:let manager = UserDefaultsManager() // ❌ 컴파일 에러!// 'UserDefaultsManager' initializer is inaccessible du..

Swift 2025.06.20

[Swift] 순열 구현하기 feat.재귀

파이썬은 permutations라는 내장함수가 있지만 swift는 만들어서 써야함 func permuteWirth(_ a: [T], _ n: Int) { if n == 0 { print(a) // 순열 완성시 출력 } else { var a = a permuteWirth(a, n - 1) // 1. 현재 상태로 재귀 for i in 0..출처 음~ 뭔말이지 ✅ 알고리즘 동작 원리종료 조건: n == 0이면 순열 완성첫 번째 재귀: 현재 상태 그대로 더 깊이 탐색스왑 + 재귀: i번째와 n번째를 바꿔가며 모든 경우 탐색백트래킹: 스왑을 되돌려 다른 경우 탐색 준비✅ 실행 과정 예시 permuteWirth([A,B..

알고리즘 2025.06.19

[iOS] MVVM 패턴에서 데이터 로딩 책임 분리

✅ 문제 상황json 파일에 있는 데이터를 파싱해와서 보여주는 과제를 하던 중 ViewController의 viewDidLoad()에서 데이터 로딩 로직을 처리하고 있는 것이 MVVM 패턴에 적합하지 않다고 느꼈다.기존 코드 (문제가 있던 코드)// BookViewController.swiftoverride func viewDidLoad() { super.viewDidLoad() setupViews() setupConstraints() // 🚨 문제: ViewController에서 데이터 로딩 제어 viewModel.loadBooks { [weak self] result in switch result { case .success: ..

iOS 2025.06.18

[Swift] Result 타입

✅ Result 타입이란?Result는 Swift 5.0에서 추가된 표준 라이브러리 타입으로, 성공과 실패를 명확하게 구분하는 enum enum Result { case success(Success) case failure(Failure)} ✅ Result의 장점1. 명확한 상태 표현// ❌ 기존 방식 - 4가지 상태 가능 (애매함)func oldStyle(completion: @escaping (Int?, NetworkError?) -> Void) { // (data, nil), (nil, error), (data, error), (nil, nil) - 뭐가 뭔지?}// ✅ Result 방식 - 2가지 상태만 (명확함)func newStyle(completion: @escaping (R..

Swift 2025.06.17

[아키텍처] Clean Architecture + MVVM

1. Clean Architecture 기본 개념3개 레이어: Presentation (UI 로직) → Domain (비즈니스 로직) ← Data (데이터 접근)의존성 규칙: 내부 레이어는 외부 레이어에 의존하지 않음핵심: 비즈니스 로직을 UI/DB로부터 완전히 독립시키는 것2. Domain Layer 상세 분석// Domain Layer 구성📁 Entities (비즈니스 모델) - Movie.swift - MovieQuery.swift📁 UseCases (비즈니스 로직) - SearchMoviesUseCase.swift - FetchRecentMovieQueriesUseCase.swift📁 Interfaces/Repositories (의존성 역전) - MoviesRepository.s..

iOS 2025.06.13

[Swift] Any와 AnyObject

오랜만에 스토리보드로 화면을 그리다가 눈에 밟히는 Any..!프로토콜에서 사용했던 AnyObject와 무슨 관련이 있는건가 궁금했다 타입캐스팅 공식문서에서 설명하고 있는 Any와 AnyObject 그리고 예상했겠지만 Any, AnyObject 둘 다 프로토콜임 ✅ 예제// Any - 모든 타입 수용let anyInt: Any = 42 // Int (값 타입)let anyString: Any = "Hello" // String (값 타입)let anyButton: Any = UIButton() // UIButton (참조 타입)// AnyObject - 클래스만 수용let objButton: AnyObject = UIButton() // 클래스// let objInt..

Swift 2025.06.12

[Swift] SOLID 원칙 iOS에 적용해보기

이론만 외우고 있던 SOLID 원칙,, 자세히 보니 이미 자연스럽게 쓰고 있었던 것들이다더 체계적으로 적용하고 활용하기 위해 정리해본다 ✅ SOLID?로버트 마틴(Uncle Bob)이 정리한 객체지향 설계 5원칙. 이 원칙들을 지키면:변경에 유연한 구조: 결합도는 낮고, 응집도는 높은 코드이해하기 쉬운 구조: 가독성이 좋고 디버깅하기 편한 코드무작정 따르는 게 아니라 판단력을 가지고 적용해야 함. 과도하게 적용하면 오히려 복잡해질 수 있음!1️⃣ SRP: 단일 책임 원칙"클래스 변경 이유는 딱 하나여야 한다""하나의 책임만 가져야 한다" -> 사실 '책임'은 주관적인 평가=> 정확한 정의: "변경의 이유가 하나, 오직 하나뿐이어야 한다"// ❌ 나쁜 예: 4가지 변경 이유를 가짐class UserView..

iOS 2025.06.10

[Swift] 캡처리스트와 순환참조

ARC 2탄 느낌으로 낋여본다class로만 순환참조 예제를 보다가 클로저랑 캡처리스트에서 순환참조가 이해가 안되어 하는 정리! ✅ 클로저도 객체다// Dog 예제var dog1: Dog? = Dog(name: "멍멍이") // 힙에 Dog 객체 생성var dog2: Dog? = dog1 // 같은 객체 참조// 클로저 예제 (동일한 원리!)var completion: (() -> Void)?let myClosure = { print("Hello") } // 힙에 클로저 객체 생성completion = myClosure // 같은 클로저 객체 참조-> 클로저도 힙에 생성되는 실제 객체이고, 변수들은 그 주소를 가리킨다!✅ 캡처(Capture)란?1...

Swift 2025.06.05