Swift. Associated Type

소개 Swift의 프로토콜은 구현이 아니라 요구사항만 정의한다. 그런데 어떤 프로토콜은 사용할 타입을 미리 알 수 없는 경우가 있다. 예를 들어, 아래와 같은 Container 프로토콜을 만든다고 생각해 보자. protocol Container { func append(_ item: ???) } append가 받을 타입은 무엇이어야 할까? Int일 수도 있고, String일 수도 있으며, 사용자가 직접 만든 타입일 수도 있다. 하지만 프로토콜이 특정 타입에 종속되면 재사용성이 크게 떨어진다. 이럴 때 사용하는 것이 Associated Type이다. 처음에는 Generic으로도 해결할 수 있을 것 같다는 생각이 들었는데, 프로토콜은 Generic을 사용할 수 없다. ...

January 26, 2025

SniffMEET. Diffable Data Source에서 이미지가 갱신되지 않은 이유

들어가며 SniffMeet의 메이트 리스트 화면은 UITableViewDataSource를 직접 구현해서 셀을 구성하고 있었다. 이후 테이블 뷰와 컬렉션 뷰에서 Diffable DataSource를 사용해보기로 했고, 먼저 메이트 리스트 화면에 적용해보려고 했다. 처음에는 어렵지 않을 거라고 생각했다. 섹션과 아이템 타입을 만들고, snapshot을 적용하면 기존 reloadData()보다 깔끔하게 업데이트할 수 있을 것 같았다. 하지만 실제로는 이미지 갱신이 제대로 동작하지 않았다. 더 정확히는 프로필 이미지 데이터는 받아오는데, Diffable DataSource가 셀을 다시 구성할 때는 이미지가 계속 nil로 남아 있었다. 결국 이 작업은 성공적으로 마무리하지 못했다. 그래도 실패한 이유를 다시 정리해보니, 문제는 Diffable DataSource API 자체가 아니라 item의 identity와 표시 상태를 제대로 구분하지 못한 데 있었다. ...

January 20, 2025

OS. IPC(Inter-Process Communication)

Date: January 19, 2025 Multi-select: Process IPC 여러 개의 독립적인 프로세스들이 서로 데이터를 주고받을 때 사용하는 메커니즘을 IPC(Inter Process Communication)라고 한다. 각각의 프로세스는 별개의 메모리 공간을 가지기 때문에, 서로 직접 메모리에 접근할 수 없기 때문에 IPC는 프로세스 간에 데이터를 교환하는 방법을 제공한다. 메세지 패싱 직접 메모리를 공유하지 않고 메세지를 통해 데이터를 주고받는 방식, 격리성을 보장할 수 있는 장점이 있지만 속도가 느리고 메모리 소비가 증가한다는 단점이 있음 주요방식 Simple 간단히 메세지를 보내고 받는 방식 ...

January 19, 2025

SniffMEET. 프로필 이미지 다운샘플링과 썸네일 분리하기

개요 사용자가 고해상도 사진을 그대로 업로드하면, 앱에서는 훨씬 작은 크기로만 이미지를 표시하는데도 원본 이미지를 계속 전송하고 저장하게 된다. SniffMeet에서도 프로필 이미지는 홈 화면의 프로필 카드나 메이트 리스트의 작은 썸네일로 표시되는 경우가 대부분이었다. 그런데 원본 이미지를 그대로 업로드하고, 목록에서도 같은 이미지를 다시 내려받고 있었다. 불필요한 네트워크 사용량과 메모리 사용을 줄이기 위해 두 가지를 적용했다. 업로드 전에 프로필 이미지를 앱에서 필요한 크기로 다운샘플링한다. 메이트 리스트에서는 원본 프로필 이미지가 아니라 별도의 썸네일 이미지를 내려받는다. 다운샘플링 기준 정하기 이미지를 어느 크기까지 줄일지 먼저 정해야 했다. 기준은 앱에서 프로필 이미지가 가장 크게 표시되는 홈 화면의 프로필 카드로 잡았다. ...

January 17, 2025

SniffMEET. OSSignposter로 앱 내부 작업 구간 측정하기

들어가며 성능 개선을 하려면 먼저 어떤 작업이 얼마나 걸리는지 볼 수 있어야 한다. CPU 사용량만 보면 어느 시점에 부하가 생겼는지는 알 수 있지만, 앱 내부의 어떤 작업이 그 구간에 실행됐는지는 바로 드러나지 않는다. 그래서 Instruments에서 앱 내부 작업 구간을 이름으로 확인할 수 있도록 OSSignposter를 래핑해보기로 했다. 어디에 붙일까? 처음에는 측정용 타입을 따로 만들지, 기존 SNMLogger에 붙일지 고민했다. private static let logger: Logger = Logger( subsystem: "SniffMeet", category: "SNMLogger" ) 별도의 SNMBenchMarker 같은 타입을 만들 수도 있었지만, 이미 프로젝트에 로그 시스템이 있었기 때문에 기존 SNMLogger에 통합하는 쪽을 선택했다. ...

January 14, 2025

SniffMEET. NI·MPC 프로필 드랍 흐름 소유권 고민하기

들어가며 SniffMeet의 프로필 드랍 기능은 주변 사용자를 찾고, 기기 간 연결을 만들고, 거리와 방향 조건을 만족했을 때 프로필을 전달하는 흐름이다. 겉으로 보면 “주변 사람 찾기"와 “프로필 보내기"를 나누면 될 것 같았다. 하지만 실제 흐름을 펼쳐보니 MPC, NI, 유즈케이스, 인터랙터가 서로 맞물려 있었고, 단순히 기능 이름으로 유즈케이스를 나누기 어려웠다. 이 글은 프로필 드랍 흐름을 유즈케이스로 나누면서 고민했던 지점을 정리한 기록이다. 기존에 생각한 흐름 당시 프로필 드랍은 대략 다음 순서로 동작한다고 봤다. ...

January 14, 2025

프로세스와 스레드

프로세스 컴퓨터에서 실행 중인 프로그램의 인스턴스, 프로그램이 메모리에 올라가면 프로세스가 된다. 프로세스의 상태 운영체제마다 세부 상태는 다르지만, 기본적인 5상태 모델은 다음과 같다. 생성(New): 프로세스가 만들어지는 중인 상태 준비(Ready): 실행에 필요한 자원을 갖추고 CPU 할당을 기다리는 상태 실행(Running): CPU에서 명령을 실행하고 있는 상태 대기(Waiting, Blocked): I/O 완료나 이벤트 발생을 기다리는 상태 종료(Terminated): 실행이 끝난 상태 CPU 스케줄러가 준비 상태의 프로세스를 선택하면 실행 상태로 이동한다. 할당 시간이 끝나거나 선점되면 다시 준비 상태가 되고, I/O를 요청하면 대기 상태로 이동한다. 기다리던 작업이 완료되면 다시 준비 상태로 돌아간다. ...

January 12, 2025

OS. Deadlock

데드락 두 개 이상의 프로세스나 스레드가 서로 상대방이 점유하고 있는 자원을 기다리며, 서로 무한히 기다리는 상태에 빠지는 현상 데드락의 발생 조건 다음 네 가지 Coffman 조건이 동시에 성립할 때 데드락이 발생할 수 있다. 각 조건은 데드락의 필요 조건이지만, 네 조건이 성립한다고 해서 모든 실행에서 반드시 데드락이 발생하는 것은 아니다. 상호 배제(Mutual Exclusion) 한 번에 하나의 작업만 사용할 수 있는 자원이 존재하는 상태다. 점유 대기(Hold and Wait) 작업이 하나 이상의 자원을 이미 보유한 상태에서 다른 작업이 가진 추가 자원을 기다리는 상태다. ...

January 12, 2025

OS. Context Switching

컨텍스트 스위칭 CPU가 현재 실행 중인 프로세스나 스레드를 중단하고, 다른 프로세스나 스레드를 실행하는 과정. 멀티 태스킹 환경에서 하나의 CPU가 여러 작업을 번갈아 가며 처리할 수 있게 만들어 준다. 언제 발생하나? CPU 스케줄러가 다른 작업을 선택했을 때(그러면 다른 프로세스를 써야하니까) 실행 중인 작업이 블로킹 되었을때 (I/ O같은게 들어왔다거나 할 때) 과정 현재 작업(프로세스, 스레드)의 컨텍스트를 저장한다. 다음에 실행할 작업의 컨텍스트를 복원한다. CPU가 새로운 작업을 실행한다. 코스트 컨텍스트 스위칭을 할 때, 상태를 저장하고 로드하는 과정에서 메모리 접근, 레지스터 저장, 복원과 같은 작업 때문에 시간과 자원을 사용하게 된다. ...

January 12, 2025

Network. URI(Uniform Resource Identifier)

URI (Uniform Resource Identifier) 자원(파일, 웹 페이지, 이메일 주소)등을 식별하는 문자열 URI는 URL과 URN을 포함하는 상위 개념이다. URL (Uniform Resource Locator) 자원의 위치(Location)와 접근 방법을 나타내는 URI HTTP, HTTPS, FTP 등의 프로토콜을 포함할 수 있다. 프로토콜, 호스트, 경로, 쿼리 등을 통해 자원에 접근하는 방법을 나타낸다. URN (Uniform Resource Name) 자원의 이름(Name)으로 식별하는 URI 자원의 위치와 관계없이 고유한 이름으로 식별한다. 대표적으로 ISBN, ISSN 등이 사용된다. 관계 URI ├── URL └── URN

January 12, 2025