(Deep Dive) 구조적 동시성은 무엇이 구조적인가
시작하게 된 이유 이전글에서 Udemy 강의를 따라가며 async let, Task Group, Task { }, Task.detached를 한 번씩 써봤다. 그다음 글에서는 랜덤 이미지 앱에 async let과 Task Group을 적용해봤다. 그때는 강의 흐름대로 “이렇게 쓰면 동시에 돈다” 정도로 정리하고 넘어갔다. 그런데 이번 Deep ...
시작하게 된 이유 이전글에서 Udemy 강의를 따라가며 async let, Task Group, Task { }, Task.detached를 한 번씩 써봤다. 그다음 글에서는 랜덤 이미지 앱에 async let과 Task Group을 적용해봤다. 그때는 강의 흐름대로 “이렇게 쓰면 동시에 돈다” 정도로 정리하고 넘어갔다. 그런데 이번 Deep ...
시작하게 된 이유 이전글 끝에서 Task와 await의 역할을 정리했다. Task는 기다릴 수 있는 공간을 만들고, await는 그 공간에서 actor에 들어갈 차례를 기다린다. actor는 한 번에 하나씩만 들어오게 해주니까, 차례를 지켜서 들어가면 안전하다고 생각했다. 그런데 다음 주제를 고르다가 “actor인데 상태가 꼬인다”는 말이 나왔...
시작하게 된 이유 이전글에서 Task에 Sendable이 아닌 값을 넘기는 실험을 했다. 함수 안에서 새로 만든 값은 넘어갔고, 넘긴 뒤에 또 쓰거나 파라미터로 받은 값은 sending ... risks causing data races 에러로 막혔다. 같은 타입인데 결과가 갈렸다. 그때는 결과만 적고 넘어갔는데, 이렇게 “타입이 아니라 값을 ...
이전 글에서 GPWS 경고와 건강 앱 중복 저장을 고쳤다. 1.3.2를 마무리하면서 두 개를 더 손봤는데, 앞의 둘과 성격이 달라서 따로 적는다. 7일 리마인더와 Pre-flight Check의 APPLE WATCH 항목이다. 기능도 화면도 다른데 틀린 자리가 같았다. 둘 다 기능이 실제로 필요로 하는 조건 대신, 그때 손에 잡히던 값을 기준으로 ...
시작하게 된 이유 nonisolated를 실전에서는 에러 지우는 용도로만 써봤다. actor isolation 에러가 나면 일단 nonisolated를 붙이거나 Task { @MainActor in }으로 감싸서 넘어갔는데, 정작 “이게 정확히 뭘 하는 키워드인가”는 설명 못 한다. 이번엔 실제 프로젝트 사례를 뒤지는 대신, nonisolated 하...
Doubly Linked List — class가 필요한 진짜 이유 새 프로젝트(멀티플랫폼 앱, landscape 고정)로 시작해서, 제네릭 doubly linked list를 구현한다. 왜 struct가 아니라 class인가 class DoublyLinkedListNode<T> { var value: T var pr...
Part 6: Memoization — 재귀의 비효율을 실측으로 확인하기 Recursion은 종종 값비싼 연산이다. Memoization은 이전에 계산한 결과를 일종의 메모장(캐시)에 저장해뒀다가, 같은 계산이 다시 필요할 때 재사용해서 성능을 크게 끌어올리는 기법이다. 전형적인 예시가 Fibonacci 수열이고, 여기서는 그 확장판인 four-bo...
Part 5: Recursion 시작하기 Recursion(재귀)을 다루는 새 섹션이다. 재귀 함수는 자기 자신을 호출하는 정의를 가진 함수이고, 언젠가 멈추게 만드는 조건(base case)이 반드시 있어야 한다. 전형적인 예가 factorial이다. 반복문으로 짜면 n! = 1 × 2 × 3 × ... × n이지만, 재귀적으로 정의하면 이렇다....
Part 4 시작: Dictionary로 문자 빈도 세기 새 주제인 Dictionary를 다룬다. 첫 문제는 문자열 text가 주어졌을 때 가장 자주 등장하는 문자를 반환하는 mostPopularCharacter다. 빈도가 같으면(tie) ASCII 값이 더 작은 문자를 반환한다. 대문자와 소문자는 다른 문자로 취급한다('A' < 'a'). ...
Part 3: 함수형(Swifty) 스타일로 다시 풀기 Part 2에서 명령형(imperative) 스타일로 풀었던 문제들을, filter/map/reduce/forEach 같은 함수형 도구를 써서 다시 풀어본다. firstDivisibleSwifty: filter + first 먼저 firstDivisible부터(이름에 있던 오타 first...