all 44

Operation Queue

본 게시글은 인프런에서 앨런님의 iOS Concurrency(동시성) 프로그래밍, 동기 비동기 처리 그리고 GCD/Operation - 디스패치 큐와 오퍼레이션 큐의 이해를 듣고 공부한 글입니다. Managing the Execution of Operations 오퍼레이션 큐는 디스패치 큐(Dispatch Queue)에서 몇 가지 기능(일시 중지, 다시 시작, 취소 등)을 추가한 것으로 내부적으로는 GCD 위에서 돌아간다. 오퍼레이션(Operation)을 start 메서드로 현재 스레드에서 실행할 수 있지만 대부분의 경우 오퍼레이션 큐(Operation Queue)에 넣어 사용한다. 오퍼레이션 큐에 추가된 오퍼레이션은 우선순위와 준비 상태, 의존성(작업 순서)에 따라 실행된다. maxConcurrentO..

swift 2022.09.11

Operation, AsyncOperation

본 게시글은 인프런에서 앨런님의 iOS Concurrency(동시성) 프로그래밍, 동기 비동기 처리 그리고 GCD/Operation - 디스패치큐와 오퍼레이션큐의 이해를 듣고 공부한 글입니다. Operation IOS에서 오퍼레이션(Operation)이란 추상 클래스로 어떤 단위적인 작업을 클래스 화하여 사용할 수 있다. 오퍼레이션은 싱글-샷 객체(Single-Shot Object)인데 인스턴스화 하여 딱 한 번만 실행 가능하기 때문이다. 따라서 작업을 재사용하기 위해서는 객체를 다시 생성해야 한다. 일반적으로 오퍼레이션 큐(Operation Queue)에 넣어 비동기적 다른 스레드에서 작업을 수행하지만 오퍼레이션 자체의 start() 메서드를 사용해 현재 스레드에서 동기적으로 사용할 수도 있다. 오퍼레..

swift 2022.09.04

Dispatch Semaphore

세마포어(Semaphore) 비동기 처리로 인해 공유 자원에 동시에 접근하여 데이터 불일치가 발생하는 경쟁 상태를 막기 위해 스레드(혹은 프로세스) 간의 동기화가 필요하다. 임계 구역(Critical Section)에 한 개의 스레드가 접근했다면 다른 스레드에서는 접근하지 못하도록 해야 한다. 세마포어(Semaphore)는 임계 구역 문제(Critical Section Problem)를 해결하기 위한 여러 가지 방법 중 한 개다. 세마포어는 양수 값\((S)\)으로 \(S\)를 수정하는 두 가지 연산을 수행한다. wait : 만약 값이 0이 아니면 하나 감소시키고 critical section에 진입한다. 그렇지 않으면 signal 연산이 실행되어 값이 증가하기 전까지 해당 작업을 차단한다. signal..

swift 2022.09.01

크루스칼 알고리즘과 정당성 증명

스패닝 트리스패닝 트리란 무향 그래프의 모든 정점을 연결하는 부분 그래프이다. 간선의 개수는 \(V-1\) 개로 트리 구조이다.  그림 1은 7개의 정점을 6개의 간선을 이용해 연결하는 올바른 스패닝 트리이다. 반면에 그림 2는 0-1-2의 정점으로 이루어진 사이클이 있으며 2, 4번 정점은 연결되어 있지 않으므로 스패닝 트리가 아니다.그림 1그림 2최소 스패닝 트리최소 스패닝 트리란 가중치가 있는 무향 그래프의 스패닝 트리 중에서 가중치의 합이 최소인 스패닝 트리이다. 최소 스패닝 트리를 구하는 알고리즘은 크루스칼 알고리즘과 프림 알고리즘이 대표적이다. 크루스칼 알고리즘가중치가 큰 간선과 가중치가 작은 간선 중 어떤 간선이 최소 스패닝 트리에 포함될 가능성이 높을까? 당연히 가중치가 작은 간선이 최소 ..

Dispatch WorkItem

func sync(execute block: () -> Void) func async(group: DispatchGroup? = nil, qos: DispatchQoS = .unspecified, flags: DispatchWorkItemFlags = [], execute work: @escaping () -> Void) 지금까지 디스패치 큐(DispatchQueue)에 클로저 형태로 작업을 보냈다. 반복되는 작업을 디스패치 큐에 매번 클로저의 형태로 보내는 것보다는 작업을 캡슐화한 디스패치 워크 아이템(Dispatch WorkItem)을 사용하는 것을 추천한다! Dispatch WorkItem 디스패치 워크 아이템은 클래스로 작업을 캡슐화할 뿐만 아니라 아래의 추가적인 기능을 제공한다. perform(..

swift 2022.08.30

Dispatch Group

디스패치 큐(Dispatch Queue)를 사용해 메인 스레드뿐만 아니라 다른 스레드에서 작업을 수행했다. 디스패치 큐를 사용함으로써 디스패치 큐에 보낸 작업이 어떤 스레드에서 동기/비동기로 실행되는 시점을 알 수 있지만 작업이 끝난 시점을 알 수는 없었다. 작업이 끝난 시점을 알기 위해서는 디스패치 그룹(Dispatch Group)을 사용해야 한다. Dispatch Group 디스패치 그룹 사용하면 하나의 작업 집합을 만들 수 있다. 하나의 집합으로 묶인 작업들은 같은 큐 혹은 서로 다른 큐에서 비동기적으로 수행된다. 여기까지는 디스패치 큐로 직접 각각 작업을 보내는 것과 차이점이 없지만 디스패치 그룹은 모든 작업이 완료되면 completion handler를 실행한다. 따라서 우리는 completio..

swift 2022.08.26

GCD(Grand Central Dispatch)

GCD(Grand Central Dispatch)란 멀티 코어 프로세서 환경에서 최적화된 프로그래밍을 할 수 있도록 애플이 개발한 프레임워크이다. Dispatch Queue에 들어온 작업을 직렬적(serially) 또는 동시적(concurrently)으로 실행한다. 큐에 들어온 작업은 시스템에 의해 생성된 스레드에서 동기적(synchronously) 또는 비동기적(asynchronously)으로 실행되며 작업이 종료되면 해당 스레드를 제거한다. DispatchQueue DispatchQueue는 3가지 종류가 있다. main global custom main 메인 디스패치 큐는 기본적으로 직렬 큐이고 메인 스레드에 작업을 배정한다. 만약 메인 스레드가 너무 오랫동안 응답하지 않으면 0x8badf00d e..

swift 2022.08.25

sync, async, serial, concurrent

서버로부터 데이터를 받기 위해 load 버튼을 누르니 UI가 멈추는 일이 발생한다. 60Hz를 지원하는 아이폰에서는 16밀리 초마다 화면을 리프레싱 한다. 위 사진에서는 사용자가 load 버튼을 누르면서 os는 서버 통신을 수행하게 되고 서버 통신으로 인해 화면 리프레싱 작업이 후순위로 미루어져 화면이 멈추는 일이 발생한 것이다. 즉 메인 스레드에서 모든 작업을 처리해 생긴 일이다. 동시성(Concurrency) 프로그래밍 동시성(Concurrency)은 일반적으로 동시에 발생하거나 존재하는 사건, 상황을 의미한다. 프로그래밍 관점에서 동시성 프로그래밍이란 싱글 프로세서에서 멀티 스레드를 동작시키기 위한 방식으로 멀티 태스킹을 위해 여러 개의 스레드가 컨텍스트 스위칭(context switching)하며..

swift 2022.08.24

RxDataSources로 multiple section collection view 구현하기

모델 정의 collectionview cell에 들어갈 데이터의 모델을 정의한다. struct Model { var color: Int } SectionModel 정의 section을 구분할 열거형을 만들고 SectionModelType 프로토콜을 채택한다. Item의 타입과 items를 구현해야 한다. Item typealias를 정의한다. Item typealias는 section안에 들어갈 item의 타입과 동일하다. public protocol SectionModelType { associatedtype Item var items: [Item] { get } init(original: Self, items: [Item]) } 다중 섹션을 구현할 것이기 때문에 열거형으로 각 section에 들어갈 ..

swift 2022.08.20

RxSwift: Combining operators

startWithobservable이 방출할 요소 앞부분에 다른 요소를 추가하는 연산자. 주로 기본 값이나 시작 값을 지정할 때 사용한다. LIFO 방식이다.let disposeBag = DisposeBag()let numbers = [1, 2, 3, 4, 5]Observable .from(numbers) .startWith(-1, -2) .startWith(-3, -4) .subscribe { print($0) } .disposed(by: disposeBag)/*next(-3)next(-4)next(-1)next(-2)next(1)next(2)next(3)next(4)next(5)completed*/concat2개의 observable를 연결하는 연산자.하나의 observab..

swift 2022.08.19