[iOS] GCD#2

RudinP·2024년 7월 18일
0

Study

목록 보기
255/258

작업을 취소하는 방법과 여러 작업을 그룹으로 묶는 방법

작업을 취소하는 방법

1. DispatchWorkItem Instance

  • 인스턴스를 만든 후 인스턴스 안에서 취소 확인

2. vc에 속성 추가 후 판단

  • vc에 판단 기준 변수를 만들고 취소인지 아닌지 판단 후 취소 확인

취소 구현

여기서는 DispatchWorkItem Instance를 이용한 취소를 구현한다.

1. 실행중인 workItem 저장 속성 추가

//GCD에서 하나의 작업을 나타내는 타입
var currentWorkItem: DispatchWorkItem?
  • workItem을 단독으로 실행하는 것도 가능하지만, 보통은 DispatchQueue 에 추가 후 실행한다.

2. workItem 생성

3. DispatchQueue에 추가

@IBAction func submitWorkItem(_ sender: Any) {
        currentWorkItem = DispatchWorkItem(block: {
            for num in 0 ..< 100 {
                print(num, separator: "", terminator: " ")
                Thread.sleep(forTimeInterval: 0.1)
            }
        })
        
        if let currentWorkItem{
            concurrentQueue.async(execute: currentWorkItem)
        }
    }

4. 취소 기능 추가

  • DispatchQueue는 작업을 취소하는 메소드를 지원하지 않는다.
  • 따라서 workItem을 별도로 저장해두다가 workItem자체의 cancel 메소드를 호출해야한다.
  • isCancelled 속성으로 확인
var currentWorkItem: DispatchWorkItem?
    @IBAction func submitWorkItem(_ sender: Any) {
        currentWorkItem = DispatchWorkItem(block: { [weak self] in
            
            for num in 0 ..< 100 {
                //isCancelled 속성을 저장해둔 workItem을 통해 접근
                guard let item = self?.currentWorkItem, !item.isCancelled else {return}
                
                print(num, separator: "", terminator: " ")
                Thread.sleep(forTimeInterval: 0.1)
            }
        })
        
        if let currentWorkItem{
            concurrentQueue.async(execute: currentWorkItem)
        }
        
        currentWorkItem?.notify(queue: concurrentQueue){
            print("Done")
        }
    }
    @IBAction func cancelWorkItem(_ sender: Any) {
        //취소
        currentWorkItem?.cancel()
    }

5. 작업이 완료된 후 특정 기능 실행하기

  • notify 를 사용한다.
currentWorkItem?.notify(queue: concurrentQueue){
     print("Done")
}

Dispatch Group

  • 여러 workItem을 하나의 그룹으로 처리하는 방법
  • 서로 다른 DispatchQueue에 추가한 workItem도 한 그룹으로 묶을 수 있으며 그룹에 포함된 모든 workItem이 완료되어야 그룹이 완료된다.

1번 방법: workItem을 큐에 추가하는 부분 위에 group.enter()

let group = DispatchGroup() //그룹 생성
    
    @IBAction func runGroup(_ sender: Any) {
        group.enter()
        concurrentQueue.async {
            for _ in 0 ..< 10 {
                print("💩")
                Thread.sleep(forTimeInterval: 0.1)
            }
            self.group.leave()
        }
        ...
  • 작업이 끝나면 group.leave()
  • leave를 하는 것을 까먹는 경우가 있기 때문에 자주 사용되진 않는다.

2번 방법: async 메소드의 파라미터로 group 전달

 @IBAction func runGroup(_ sender: Any) {
        concurrentQueue.async(group: group) {
            for _ in 0 ..< 10 {
                print("💩")
                Thread.sleep(forTimeInterval: 0.1)
            }
        }
        ...
  • 그룹에도 notify 메소드가 있다.
group.notify(queue: DispatchQueue.main){
      print("Done")
}
profile
iOS 개발자가 되기 위한 스터디룸...

0개의 댓글