Swift 개념들 정리
오토 레이아웃에 대해 설명하세요
뷰 계층 구조에 있는 모든 뷰의크기와 위치를 해당 뷰에 적용된제약 조건에 따라동적으로 계산해주는 레이아웃 시스템- 앱이 실행되는 순서
- 운영체제가 저장장치에 있는 앱 바이너리 파일(.app)을 읽어 RAM 으로 로드합니다.
- 바이너리 파일이 RAM에서 앱 리소스, 코드파일 등을 RAM으로 지연 로딩합니다.
- CPU가 코드 파일의 진입지점인 @main 혹은 UIApplicationMain을 찾아서 실행을 시작합니다.
- 앱 생명주기 함수들이 호출되면서 CPU는 뷰컨트롤러와 UI 구성 요소를 초기화 합니다.
- CPU가 렌더링 로직을 처리한 후 GPU로 전달하여 화면에 그린다.
- CPU와 메모리 간의 데이터 교환은 어떻게 이루어지나요?
- 버스를 통해 이루어지는데 버스에는 3가지 종류가 있습니다.
주소버스,데이터버스,제어버스. 처음 CPU가 명령을 실행할 때 주소버스를 통해 데이터버스 주소를 전송합니다. 동시에 제어버스에 접근하여 읽기 or 쓰기 제어 명령을 전송합니다. 그 다음 메모리 컨트롤러에서 주소와 제어 명령으로 데이터 버스에 접근하여 데이터를 읽어 CPU의 레지스토리로 전송합니다.
- 버스를 통해 이루어지는데 버스에는 3가지 종류가 있습니다.
- 개념
- 프로토콜이란:
- 프로토콜을 따르는 타입은 정의되어있는 속성과 함수를 따라야 한다는 약속
- mutating 키워드란
- var로 인스턴스가 할당된 struct에서 내부 프로퍼티를 변경하는 함수에다가 붙이는 키워드
- 부연설명: struct는 값타입이라서 인스턴스를 생성하면 해당 구조체가 복사된다. 그 상태에서 let으로 선언된 인스턴스는 값을 변경할 수 없고 var로 선언된 인스턴스의 값을 변경할려면 mutating으로 선언된 함수에 한해서만 프로퍼티를 변경할 수 있다.
- 제네릭이란 :
타입을 매개변수처럼받아 다양한 타입에하나의 코드로 재사용이 가능하게 만드는 기능이다.
- 객체지향 프로그래밍이란:
- 속성, 함수 등을 캡슐화하고 객체를 만들기 위한 설계도로 객체를 생성하는 방식의 프로그래밍 방법론이다.
- 클래스와 구조체의 차이는?
- 클래스는 참조하는 방식으로 동작하고 구조체는 값을 복사하는 방식으로 동작한다.
SwiftUI와 UIKit의 차이점은?
SwiftUI UIKit 형식 선언형(UI를 상태기반으로 선언, 상태에 따라 UI 자동 업데이트) 명령형(UI 구성과 변경을 코드로 직접 변경, 뷰를 직접 만들고 변경할 때 수동으로 처리) 이벤트 처리 상태(State)와 바인딩 중심, Combine과 연계 강점 델리게이트, 타겟-액션 패턴 중심 미리보기 미리보기 가능 미리보기 불가능 - init, convenience init(클래스에서만 존재) 차이
- init은 모든 값을 초기화하고 상위 클래스의 지정 생정자를 호출해야 한다.,
- convenience init은 클래스의 다른 init을 호출하는 선택적으로 작성하는 함수이다.
- KVO란
- KVO는 Objective-C 런타임 기반으로, 특정
객체의 프로퍼티 값 변화를자동으로 관찰할 수 있는 메커니즘입니다. Swift에서는 @objc dynamic 키워드와NSObject 상속이 필요하고, 최근에는 Combine이나 SwiftUI의@Published로 대체되는 추세입니다.
- KVO는 Objective-C 런타임 기반으로, 특정
- 앱 생명주기
- 앱이 실행되고 종료되는 일련의 상태 변화
- Not running, InActive, Active, Background, Suspended
- 생명주기 이벤트에 따라 앱의 상태를 관리해야 합니다.
- CoreData
- Core Data는 iOS에서 객체를 저장·관리하는 프레임워크다.
- Realm대신 CoreData를 사용한 이유
- 애플 공식 프레임워크라 자연스럽게 통합되어 있고, 추가 의존성 없이 바로 사용이 가능하기 때문. Xcode에서 시각적으로 모델링 가능하며, 자동으로 클래스 생성도 지원한다.
- 데이터 흐름과 동작 원리
NSManagedObjectModel로 정의한 데이터 모델의 설계도를 RAM으로 올린다.NSPersistensStoreCoordinator로 설계도를 기반으로 DB에 연결을 한다.- context를 생성한 후 그 메모리 공간에서 가져온 데이터 모델을 기반으로 생성, 수정, 삭제 로직을 수행하고 context.save()를 해서 실제 저장 공간에 데이터를 저장한다.
NSPersistentContainer는 이 모든 것을 한번에 해주는 매니저 클래스이다.
- 프로토콜이란:
- 디자인 패턴, 아키텍처
- Delegate pattern:
- 한 객체가 자신의
작업 중 일부를다른 객체에게 위임하는디자인 패턴이다. 프로토콜을 사용해 정의하고, 위임받는 객체가 이를 구현한다.
- 한 객체가 자신의
- 싱글톤 패턴:
- 전역 인스턴스 공유용
- MVI 패턴: Intent → ViewModel, State → View
- Model-View-Intent의 약자로 사용자의 Intent(행동)에 따라 ViewModel이 State를 생성한다. 그러면 State를 구독하고 있던 View가 새로 그려지게 되는 구조이다.
- Delegate pattern:
- UIKit 관련
- viewController 생명주기
- 뷰컨트롤러 생명주기는 뷰가 생성되고 사라지는 일련의 매커니즘
- 테이블, 컬렉션 뷰 / 셀 재사용 메커니즘
- 테이블 뷰 : 수직 스크롤 리스트
- 컬렉션 뷰 : 격자형, 자유로운 레이아웃
- 셀 재사용:
- 셀을 등록
- 재사용큐에서 셀을 요청
- 재사용된 셀에 데이터를 할당해서 표시
- 메모리와 CPU 사용량을 줄일 수 있음
- frame, bounds 차이
- frame: 부모뷰 기준으로 자신의 뷰가 위치한 좌표
- bounds: 자신의 좌표계 기준으로 자신의 위치 (보통 0,0)
- UI는 왜 메인 스레드에서만 그려지는가?
- 상태 변화가 동시에 여러 스레드에서 일어나면 일관성 없는 화면이 나타날 수 있기 때문에 순차적으로 메인 스레드에서 처리해야 안정적이다.
- viewController 생명주기
- SwiftUI 관련 개념
SwiftUI의 장점: 선언형 코딩, 코드 간결성, 실시간 미리보기 가능성
State 뷰 내부에서 사용하는 상태 값. 해당 값이 변경됨에 따라 이 값을 소유한 뷰는 재렌더링된다.
Binding 외부의 State 상태값을 참조하여 양방향으로 데이터 바인딩할 때 사용한다. 원본 상태값이 바뀌면 현재 뷰도 렌더링되며, 해당 상태값은 직접 소유하지 않는다.
StateObject
ObservableObject를 채택한 클래스 타입 상태를 소유하고, 해당 객체의 생명주기를 관리한다. 뷰가 다시 그려져도 해당 인스턴스는 유지된다. 해당 클래스 내부의@Published속성은 그 인스턴스의 프로퍼티 변경 감지를 가능하게 한다.ObservedObject @ObservedObject는 ObservableObject를 채택한 클래스 인스턴스를 외부에서 주입받아 관찰만 하는 속성 래퍼다. 즉, 뷰가 소유하지 않고 단순히 관찰만 한다. 생명주기는 외부에서 관리한다.
- 메모리 관련
메모리 누수의 원인 인스턴스가 서로를 강하게 참조할 때 서로 참조 카운트가 0이 되지 않기 때문에 ARC가 메모리 해제를 못하기 때문에 순환 참조가 발생
강한 참조(strong) / 약한 참조(weak/unowned) 차이 강한 참조는 ARC가 참조 카운트를 증가시키고 약한 참조는 그렇지 않음
- 메모리에서 힙과 스택이란
- 힙 메모리: 참조 타입(class 인스턴스), 클로저, 캡처된 상태 등이 저장됨. 런타임에 동적 할당, 크기가 유동적 ARC가 참조 카운트를 추적해서 메모리 해제 시점 결정(수동 해제)
- 스택 메모리: 함수 호출 시 생성되는 지역 변수, 매개변수, 값타입(struct, enum) 등이 저장됨. 스코프(함수 범위)가 끝나면 자동 해제 컴파일 타임에 크기가 결정되고 메모리 할당/해제가 빠르다(LIFO 구조)
- ARC란? (메모리 자동 해제 시스템)
- ARC는 몇개의 참조를 가지고 있는지 카운팅하여 카운팅이 없는 객체를 자동으로 메모리 해제시켜주는 방식이다.
- 강한 참조를 기본적으로 사용하기 때문에 순환 참조가 발생할 경우 약한 참조로 메모리 누수를 방지한다. weak 키워드는 옵셔널 변수에만 사용이 가능하다.(참조 해제가 되면 자동으로 nil로 되어야 하기 때문)
- 순환 참조란?
- 두 객체가 서로를 참조하게 되어
참조 카운팅이 0이 되지 않는 상태입니다.
- 두 객체가 서로를 참조하게 되어
- 클로저 캡쳐란? 클로저에서 지역변수나 매개변수를 참조하고 있는 경우, 해당 변수들을 힙에 저장하여 클로저가 참조할 수 있도록 하는 것
This post is licensed under CC BY 4.0 by the author.