티스토리 뷰
OperationQueue 란,
동시성(Concurrecny) 프로그래밍 을 위해 iOS 환경에서 지원하는 라이브러리 입니다.
동시성(Concurrecny) 프로그래밍에 대한 자세한 설명은 동시성, 비동기 프로그래밍 톺아보기 에서 확인해 주세요 ㅎㅂㅎ
OperationQueue
이름을 살펴보면 Opertaion + Queue 인데,
말 그대로 대기열(Queue)에 추가한 동작(Operation) 의 실행을 관리하는 추상 클래스입니다.
동작에는 연산 객체(Operation Object)가 들어가게 되고, 이는 Foundation 프레임워크의 Operation 클래스 인스턴스입니다.
대기열(Queue)에서 동작(Operation) 관리
//연산 객체(Operation Object)를 대기열(Queue)에 추가합니다.
func addOperation(_ op: Operation)
func addOperations(_ ops: [Operation], waitUntilFinished wait: Bool)
//전달한 클로저를 연산 객체(Operation Object)에 감싸서 대기열(Queue)에 추가합니다.
func addOperation(_ block: @escaping () -> Void)
//대기 중이거나 실행 중인 모든 연산(Operation)을 취소합니다.
func cancelAllOperations()
//대기 중인 모든 연산(Operation)과 실행 중인 연산(Operation)이 모두 완료될 때까지 현재 스레드로의 접근을 차단합니다.
func waitUntilAllOperationsAreFinished()
- 연산(Operation) 실행 관리
//동시에 실행할 수 있는 연산(Operation)의 최대 수입니다.
var maxConcurrentOperationCount: Int { get set }
//대기열 작업을 효율적으로 수행할 수 있도록 여러 우선순위 옵션을 제공합니다.
var qualityOfService: QualityOfService { get set }
// 대기열(Queue)의 연산(Operation) 여부를 나타내기 위한 부울 값입니다.
//false인 경우 대기열(Queue)에 있는 연산(Operation)을 실행하고,
//true인 경우 대기열(Queue)에 대기 중인 연산(Operation)을 실행하진 않지만
//이미 실행 중인 연산(Operation)은 계속 실행됩니다.
var isSuspended: Bool { get set }
Example) 매우 큰 이미지 보여주기
구글에서 이미지 제일 큰놈으로다가 골라줍니다. 이미지를 클릭하시면 이미지 링크를 확인하실 수 있어요
이제 프로젝트를 만들어주고 스토리보드에 버튼과 이미지뷰를 추가해줍니다.
이미지 로딩을 위해 버튼의 action을 viewcontroller에 연결해주세요
**참고로 보안되지 않은 http 주소에서 파일 다운로드를 할 경우 아래와 같이 info.plist에 add row 해줍니다.
애플에서 보안은 생명이니까요...
@IBOutlet weak var imageView: UIImageView!
@IBAction func touchUpDownloadButton(_ sender: Any) {
//big image url
guard let imageURL: URL = URL(string: "https://upload.wikimedia.org/wikipedia/commons/3/3d/LARGE_elevation.jpg") else {
return
}
do {
let imageData: Data = try Data.init(contentsOf: imageURL)
let image: UIImage = UIImage(data: imageData) ?? UIImage()
self.imageView.image = image
} catch {
print("load image fail")
}
}
코드는 위와 같습니다. URL에서 이미지를 받아오는 로직이어요.
바로 실행시켜보겠습니다.
버튼이...?
저 매우 거대한 이미지를 받아오느라 화면이 멈춘것을 (버튼확인) 볼 수가 있습니다.
아니 어떤 앱에서 이미지 보여준다고 화면이 멈춰..?
맞습니다.. 그럼 사용자가 다 도망가겠죠..
이걸 고쳐야 하는데 왜 이런 문제가 생겼을까요?
let imageData: Data = try Data.init(contentsOf: imageURL)
바로 이 부분이 문제입니다.
네트워킹 작업을 하면서 imageData를 받아오는 코드가 현재 UI를 담당하는 main thread에서 돌고 있기 때문입니다.
여기서 저희가 배운 OperationQueue를 이용해서 이미지 다운로드 받는 작업을 백그라운 스레드로 Queue 에 담아버리겠습니다.
main thread 가 아닌 다른 흐름에서 동작하도록 말이죠.
OperationQueue().addOperation {
do {
let imageData: Data = try Data.init(contentsOf: imageURL)
let image: UIImage = UIImage(data: imageData) ?? UIImage()
self.imageView.image = image
} catch {
print("image faiil")
}
}
잘- 담겼습니다. 한번 실행을 해볼까요?
오 뭔가..
뭔가 멈춤은 없는데
내 사진 어딨지?
음?
UIImageView의 image 를 변경하는 작업, 즉 UI 를 변경하는 작업은 다시 main thread에서 해야하기 때문에 저런... 경고가 뜹니다.
OperationQueue.main.addOperation {
self.imageView.image = image
}
image 를 변경하는 부분을 main thread 에서 작업하도록 명시를 해주고 다시 실행을 시켜보겠습니다.
이제 멈춤 현상없이 이미지 다운로드 작업이 잘되는 것을 확실할 수 있습니다
간단하게 작업에 대해서 각각 스레드를 지정해주어 보았습니다.
활용할 수 있는 방향이 상당히 많을 것 같다는게 느껴지시나요..?
오늘은 여기서 마치겠습니다.
20000~~
'iOS' 카테고리의 다른 글
[iOS] Navigation Item 톺아보기 (0) | 2019.08.22 |
---|---|
[iOS] ScrollView 톺아보기 (0) | 2019.08.22 |
[iOS] 동시성, 비동기 프로그래밍 톺아보기 (0) | 2019.08.21 |
[iOS] Photos 프레임워크 톺아보기 (2) | 2019.08.10 |
[iOS] Codable 톺아보기 (0) | 2019.08.01 |