GCD 사용 시 주의해야 할 사항

brick·2023년 2월 28일
0

Concurrency Programming

목록 보기
3/6
post-thumbnail

UI처리는 Main Queue에서

UI 관련 일들은 Main Queue에서 처리해야 한다.

DispatchQueue.global().async {
    //이미지 다운로드 코드
    
    DispatchQueue.main.async {
        // 다운로드한 이미지 표시는 main 쓰레드에서 한다.
        self.imageView.image = image
    }
}

URLSession.shared.dataTask(with: urlRequest) {
    // 이미지 다운로드 코드
    
    DispatchQueue.main.async {
        // 다운로드한 이미지 표시는 main 쓰레드에서 한다.
        self.imageView.image = image
    }
}



Sync메서드 주의사항

Main Queue에서 다른 큐로 보낼때 sync메서드를 사용하면 안된다.

Main 쓰레드는 UI 업데이트를 담당함으로 동기적(sync)으로 시키면 UI가 멈춰 반응이 늦어지고 버벅거린다.


현재의 큐에서 현재의 큐로 동기적으로 보내서는 안된다

현재의 큐를 블락하는 동시에 다시 현재의 큐에 접근하기 때문에 교착상황(DeadLock)이 발생한다. (다시 현재의 큐에 배치되는 경우에)



weak, Strong 캡처 주의

클로저의 강한 참조를 주의 해야한다.

DispatchQueue.global(qos: .utility).async { [weak self] in
    guard let self = self else { return }
    
    DispatchQueue.main.async {
        self.textLabel.text = "new!"
    }
}


Completion Handler 사용하는 이유

비동기 작업이 끝나는 시점에 해당 값들에 접근해서 사용하기 위해 사용한다.



동기적 함수를 비동기함수 처럼 만드는 방법

재활용을 위해서 사용한다.

func asyncTiltShift(_ inputImage: UIImage?,
                    runQueue: DispatchQueue,
                    completionQueue: DispatchQueue,
                    completion: @escaping (UIImage?, Error?) -> ()) {
    runQueue.async {
        var error: Error?
        error = .none
        
        // 동기적으로 동작하는 함수
        let outputImage = tiltShift(image: inputImage)
        
        completionQueue.async {
            completion(outputImage, error)
        }
    }
}


참고

0개의 댓글