← 홈으로 돌아가기

📝 Daily Learning Log (2026-06-15 ~ 06-21)

주간 학습일지 · 2026-06-15 ~ 06-21

2026-06-15 (월)

✅ 학습 완료

💡 핵심

PAT(Associated Type/Self) 사용 규칙:
  • let box: Container ❌ → Generic constraint 필요 <T: Container>
  • item + 1 ❌ → where 절 필요 where T.Item: Numeric
컴파일 vs 링킹:
  • 컴파일: .swiftmodule로 타입 체크 → .o에 심볼 이름만 기록 (주소 미정)
  • 링킹 (ld): 심볼 이름 → 실제 주소로 패치, .swiftmodule 사용 안 함
  • Dynamic: 링킹 때 참조만 기록, 런타임에 dyld가 주소 바인딩

📕 오답노트

2026-06-16 (화)

✅ 학습 완료

💡 핵심

더티 플래그 3종 (가장 중요!):
트리거불리는 메서드하는 일
setNeedsUpdateConstraints()updateConstraints()제약 재구성
setNeedsLayout()layoutSubviews()frame 재배치
setNeedsDisplay()draw(_:)비트맵 다시 그리기

📕 오답노트

제약 직접 변경 시 setNeedsUpdateConstraints() 필요?

  • ❌ 불필요. constraint.constant = 200needsLayout만 자동 설정
  • updateConstraints()는 안 불림 — layout 패스에서 제약 풀어 frame만 계산
  • setNeedsUpdateConstraints()updateConstraints() 오버라이드할 때만 사용

2026-06-17 (수)

✅ 학습 완료

💡 핵심

some 쓰는 이유:
  • 복잡한 타입 숨기기 (LazyMapSequence<...>some Sequence)
  • 내부 구현 변경해도 API 시그니처 유지
  • Static Dispatch 성능 유지
  • SwiftUI var body: some View
Existential이란:
  • "프로토콜을 타입처럼 쓰는 것" = Existential Type
  • Existential Container = Value Buffer + Type Metadata + PWT
  • some = 투명 상자 (컴파일러가 앎) / any = 불투명 상자 (런타임에 열어봄)

📕 오답노트

some은 "여러 타입에 대해 사용"하는 게 아니다

  • ❌ 틀린 정의: "호출자가 여러 conform 타입에 대해 사용할 때"
  • ✅ 맞는 정의: some항상 같은 하나의 구체 타입만 반환
  • 여러 타입 반환하려면 any 사용
// some: 항상 같은 타입
func make() -> some Numeric { return 42 }  // 항상 Int

// any: 여러 타입 가능
func make(flag: Bool) -> any Numeric {
    flag ? 42 : 3.14  // Int 또는 Double
}

Swift 5.7 이하에서 any + PAT 가능했나?

  • ❌ 아니다. 5.7 이상에서 가능해짐
  • 5.6 이하: any Sequence 불가능 → Generic으로만 사용
  • 5.7+: any Sequence 가능해짐

Generic은 같은 모듈이면 인라인, 다른 모듈이면 PWT 전달?

  • 거의 맞음. 단, "PWT를 구현체에" → "PWT를 제네릭 함수에" 전달
  • 같은 모듈: Specialization → 타입 전용 함수 생성 → 인라인 가능
  • 다른 모듈: 본문 안 보임 → PWT를 제네릭 함수에 전달
  • 둘 다 컴파일타임에 T 결정됨 (any와 다른 점)
같은 모듈:
f(Dog()) → f_Dog() 생성 (Specialization) → 인라인

다른 모듈:
f(Dog()) → f<T>() + Dog의 PWT 전달 → 테이블 조회

둘 다 컴파일타임에 T=Dog 확정

[Shape]만 쓰면 안 돼? any 없이?

  • Swift 5.6 이하: [Shape] OK (암묵적 existential)
  • Swift 5.7+: [any Shape] 필수 (명시적)
  • any 키워드: 5.6에서 도입 → 5.7에서 필수화

Struct 캡쳐하면 값이 복사될까?

  • ❌ 아니다. Struct도 기본적으로 참조 캡쳐된다
  • 변수가 Box에 담겨 힙으로 이동 → 외부 변경 시 클로저에서도 변경된 값 보임
  • 값 복사 원하면: Capture List { [def] in ... } 사용
struct DEF { var t = 12 }
var def = DEF()

// ❌ 참조 캡쳐 (기본)
let c1 = { print(def.t) }
def.t = 100
c1()  // 100

// ✅ 값 캡쳐
var def2 = DEF()
let c2 = { [def2] in print(def2.t) }
def2.t = 100
c2()  // 12 (복사됨)

Class를 Capture List로 캡쳐하면 값 복사?

  • ❌ 아니다. [abc]는 레퍼런스만 복사됨
  • Class는 본질적으로 레퍼런스 타입
  • 값 복사 원하면: [copiedT = abc.t] 또는 새 인스턴스 생성

2026-06-18 (목)

✅ 학습 완료

💡 핵심

스택 프레임 구조:
  • Return Address: 돌아갈 코드 주소 (Code Segment)
  • Saved FP: 이전 함수의 스택 프레임 주소 (Stack)
  • FP 위치: Saved FP 바로 아래 (프레임 "맨 위" 아님)
CPU 레지스터 3종:
레지스터가리키는 곳특성
PC (Program Counter)Code Segment현재 실행 명령어
FP (Frame Pointer)Stack함수 내 고정
SP (Stack Pointer)Stack계속 이동

📕 오답노트

메모리 주소 순서 — Code가 높은 주소?

  • ❌ 틀림. Code가 가장 낮은 주소
  • 순서: Code(낮음) → Data → Heap → Stack(높음)
  • Heap은 ↓(높은 주소로), Stack은 ↑(낮은 주소로) 성장

FP는 프레임 맨 위(높은 주소)?

  • ❌ 아니다. FP는 Saved FP 바로 아래를 가리킴
  • 위로(+): Return Addr, Saved FP 접근
  • 아래로(-): 지역변수 접근 (FP - 8, FP - 16)

Stack Overflow = 힙 영역 침범?

  • ❌ 아니다. 스택이 자신의 한계(1~8MB)를 초과하는 것
  • Guard Page가 힙-스택 사이를 보호
  • 무한 재귀 = 대표적 원인

2026-06-19 (금)

📖 현재 뷰 레이아웃 전체 과정 심화 정독·복습 중

✅ 학습 완료

📕 오답노트

a1.layoutSubviews()는 a1의 frame을 정하는 것?

  • 아니다. "subviews를 layout" → a1이 자식 a2의 frame을 정함. a1 자신 frame은 부모(VC.view)가 정함
  • layoutSubviews = frame set까지만. draw·GPU render는 그 이후 별도 단계

2026-06-20 (토)

📖 뷰 레이아웃 전체 과정 심화 복습 중 — 오늘 "6. 실무 함정 체크"까지 읽음

✅ 학습 완료

2026-06-21 (일)

✅ 학습 완료

  • 📄 ScrollView · TableView · CollectionView 원리 & 심화 (신규)
    • 스크롤의 본질=bounds 이동(contentOffset==bounds.origin), TableView/CollectionView는 ScrollView 서브클래스
    • 셀 재사용(visible rect→pool→dequeue), prepareForReuse 함정(잔상·비동기 취소)
    • self-sizing(automaticDimension+estimated), Diffable(Hashable 해시 diff), Compositional Layout
    • 스크롤 60fps — 오프스크린 렌더링·메인스레드 디코딩·블렌딩 회피, 이미지 다운샘플
  • 📄 스크롤뷰 학습 중 내 질문 Q&A 15문항 (신규)
    • ScrollView 재사용 없음·lazy 생성=cellForItem, TableView 레이아웃은 내부 관리
    • bounds.origin=보는 창 이동(콘텐츠 고정), frame/bounds/contentSize, contentInset 530 계산
    • contentLayoutGuide/frameLayoutGuide·bottom 핀, self-sizing(systemLayoutSizeFitting·offset 보정)
    • prefetching=프로토콜, batch vs Diffable, moveRow(IndexPath), 레이아웃 attributes·zIndex
    • frame 직접=텍스트 수동 계산(boundingRect/sizeThatFits) vs Auto Layout 자동(intrinsic, line height 포함)
  • 📕 오답노트

    duplicate symbol은 "같은 함수를 사용"하면 나는가?

    • 아니다. 결정 요인은 사용 함수가 아니라 정의가 두 벌 최종 바이너리에 들어오느냐(= 모듈을 embed했느냐)
    • "호출부에 코드 붙여넣기"는 embed가 아니라 인라이닝. embed=.o를 아카이브에 별도 포함
    • static framework는 실행파일이 없어 쓰는 쪽에 코드 복사 → dynamic+앱 동시 사용 시 두 바이너리에 복제