[iOS] GCD #1

RudinP·2024년 7월 16일
0

Study

목록 보기
254/258
post-thumbnail

GCD

  • Grand Central Dispatch
  • 모든 애플 플랫폼에서 사용 가능
  • 스레드 생성, 관리
  • 스레드 풀을 통해 스레드 재사용, 시스템 리소스를 적게 사용

Dispatch Queue & Work Item

  • GCD의 핵심 개체
  • Work Item: 실행할 코드
  • Dispatch Queue: 작업을 관리하는 객체
  • Dispatch Queue에 Work Item을 추가하면 추가한 순서대로 작업이 실행된다. 이러한 모델을 Work-Queue Programming Model이라고 한다.

Serial Queue & Concurrent Queue

  • Dispatch Queue의 작업 방식
  • Serial Queue: 추가된 작업을 순서대로 실행(기본)
  • Concurrent Queue: 동시에 작업을 실행(concurrent 옵션으로 생성)

Global Queue & Main Queue

DispatchQueue.global().async{ //백그라운드 스레드. async는 작업을 큐에 추가하는 메소드
            for num in 1 ... 100{
                
                DispatchQueue.main.async{ //메인스레드
                    self.countLabel.text = "\(num)"
                }
                Thread.sleep(forTimeInterval: 0.1)
            }
        }
  • global : 백그라운드 스레드에서 동작하는 기본 큐
  • main : 메인스레드에서 동작하는 기본 큐
    • 메인 큐는 앱 시작 시점에 자동으로 생성
    • serial 함
    • UI에 관련된 작업은 반드시 main에서 실행

Dispatch Queue 생성

let serialQueue = DispatchQueue(label: "SerialQueue") // serial Queue
let concurrentQueue = DispatchQueue(label: "ConcurrentQueue", attributes: .concurrent) // concurrent Queue

Work Item 생성

sync & async

//sync
    @IBAction func sync(_ sender: Any) {
        concurrentQueue.sync {
            for _ in 0 ..< 3 {
                print("Hello")
            }
            
            print("# Point 1")
        }
        
        print("# Point 2")
    }
//async
    @IBAction func async(_ sender: Any) {
        concurrentQueue.async {
            for _ in 0 ..< 3 {
                print("Hello")
            }
            
            print("# Point 1")
        }
        
        print("# Point 2")
    }
  • sync, async는 실행하는 메소드가 아닌, 큐에 work item을 추가하는 메소드다.
  • 실제 작업 실행은 dispatchQueue
  • async와 sync가 dispatchQueue의 동작 방식에는 영향을 주지 않는다.
    • serial Queue에 추가할 때 둘 중 어느것을 사용하던 항상 작업을 순서대로 실행한다.
    • concurrent Queue에 추가할 때 둘 중 어느것을 사용하던 동시에 작업을 실행한다.

sync 결과

  • sync는 동기 방식으로 work를 추가
  • work아이템을 추가한 다음 바로 리턴하지 않고 실행이 끝날 때까지 기다린다.
  • 주로 lock과 유사한 동기화를 구현할 때 사용
  • mainQueue에서 sync를 사용하면 크래시가 발생하므로 주의하자.

async 결과

  • async는 비동기 방식으로 work를 추가
  • work아이템을 추가한 다음 바로 리턴하므로 이어지는 코드가 바로 실행된다.
  • 스레드를 블로킹하지 않으므로 대부분은 async로 work 아이템을 추가한다.

asyncAfter로 실행 시간 지연

@IBAction func delay(_ sender: Any) {
        let delay = DispatchTime.now() /*현재 시간을 리턴*/ + 10
        
        concurrentQueue.asyncAfter(deadline: delay) {
            print("# Point 1")
        }
        
        print("# Point 2")
    }

Point 2 바로 출력 후 10초 뒤에 Point 1 출력
  • asyncAfter은 비동기 메소드
  • 지정한 시간에 작업을 예약하고 바로 리턴

병렬 실행

DispatchQueue.concurrentPerform(iterations: , execute: (Int) -> Void)
  • execute 블럭을 iterations만큼의 횟수로 병렬 실행
    @IBAction func concurrent(_ sender: Any) {
        //일반 코드
        var start = Date.now
        
        for index in 0 ..< 50 {
            print(index, terminator: " ")
            
            Thread.sleep(forTimeInterval: 0.1)
        }
        
        print()
        
        var end = Date.now
        
        print("serial: \(end.timeIntervalSinceReferenceDate - start.timeIntervalSinceReferenceDate)")
        
        start = Date.now
        
		//병렬 코드
        DispatchQueue.concurrentPerform(iterations: 50) { index in
            print(index, terminator: " ")
            
            Thread.sleep(forTimeInterval: 0.1)
        }

        print()
        
        end = Date.now
        
        print("serial: \(end.timeIntervalSinceReferenceDate - start.timeIntervalSinceReferenceDate)")

    }

  • 보통 병렬로 실행할 수 있는 작업의 수는 CPU의 코어 수와 동일
profile
iOS 개발자가 되기 위한 스터디룸...

0개의 댓글