210429 Thu

1. 첫 번째 학습 내용: OperationQueue를 활용하여 비동기 프로그래밍 해보기

import UIKit

class ViewController: UIViewController {
    
    @IBOutlet weak var imageView: UIImageView!
    
    @IBAction func touchUpDownloadButton(_ sender: UIButton) {
        // 이미지 다운로드 -> 이미지 뷰에 셋팅
        
        // https://upload.wikimedia.org/wikipedia/commons/3/3d/LARGE_elevation.jpg
    
        OperationQueue().addOperation {
            let imageURL: URL = URL(string: "https://upload.wikimedia.org/wikipedia/commons/3/3d/LARGE_elevation.jpg")!
            let imageData: Data = try! Data.init(contentsOf: imageURL)
            let image: UIImage = UIImage(data: imageData)!

            self.imageView.image = image
        }
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
    }
}

UI와 관련된 코드는 메인 스레드에서 관리해야 함

import UIKit

class ViewController: UIViewController {
    
    @IBOutlet weak var imageView: UIImageView!
    
    @IBAction func touchUpDownloadButton(_ sender: UIButton) {
        // 이미지 다운로드 -> 이미지 뷰에 셋팅
        
        // https://upload.wikimedia.org/wikipedia/commons/3/3d/LARGE_elevation.jpg
    
        let imageURL: URL = URL(string: "https://upload.wikimedia.org/wikipedia/commons/3/3d/LARGE_elevation.jpg")!

        OperationQueue().addOperation {
            let imageData: Data = try! Data.init(contentsOf: imageURL)
            let image: UIImage = UIImage(data: imageData)!
            
            OperationQueue.main.addOperation {
                self.imageView.image = image
            }
        }
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
    }
}

OperationQueue.main.addOperation
→ 메인 스레드로 보내주면 이제 이미지 버벅거리거나 화면 멈추지 않음 !!

let queue = OperationQueue()
       queue.addOperation {
            let imageData: Data = try! Data.init(contentsOf: imageURL)
            let image: UIImage = UIImage(data: imageData)!
            
            OperationQueue.main.addOperation {
                self.imageView.image = image
            }
        }

출처: 부스트코스 iOS 앱 프로그래밍

2. 두 번째 학습 내용: maxConcurrentOperationCount

Q. Operation Queue에서 비동기 어떻게 적용?!!
Operation Queue에는 디스패치 큐처럼 .async나 sync 이런게 없는데?
A. Operation Queue에 넣어주면 알아서 비동기로 실행됨
(= 고로 따로 비동기 설정을 해줄 필요가 없다)

When you submit a nonconcurrent operation to an operation queue, the queue itself creates a thread on which to run your operation. Thus, adding a nonconcurrent operation to an operation queue still results in the asynchronous execution of your operation object code.

Concurrency Programming Guide

Q. Operation Queue 비동기로 하면
Step1 실행 예시처럼 동기로 되게 하려면 어떻게 함??
A. 스티븐은 maxConcurrentOperationCount라는 Instance Property를 1로 설정해줬다고 함.
은행원 1명만 되는거임.
그러면 동기처럼 처리가 됨.

Instance Property

maxConcurrentOperationCount

The maximum number of queued operations that can execute at the same time.

→ 동시에 실행될 수 있는 queued operation의 최대 갯수

Instance Property

isAsynchronous

In a concurrent operation, your start() method is responsible for starting the operation in an asynchronous manner.

그럼 start() method쓰면 비동기 선언 따로 안해줘도 된다는건가??

→ 요 아이는 어떻게 쓰는건지 모르겠음.. 🤔

일단 패스!

[iOS 앱개발] GCD - OperationQueue로 동시성 구현해보기

3. 세 번째 학습 내용: BlockOperation

Performing the Main Task

모든 opration객체는 최소한 다음 메소드를 구현해야합니다.

● custom initialization method(커스텀 초기화 메소드)
무슨 말인지 모르겠다 헤

● main
If you are creating a concurrent operation, you need to override the following methods and properties at a minimum:

  • start()
  • isAsynchronous
  • isExecuting
  • isFinished

Q. Operation Queue가 단순히 큐 만들고 addOperation하면 되는게 아니라
저 메소드들을 다 써줘야 하는건가??
어떻게??? ^.ㅠ
최소 (필수로) 재네들 써야 한다고 나와만 있고 예시가 없다 끙... 😢

→ 지금 당장 필요한게 아니면 안 써줘도 됨.

스티븐 말로는 방법이 2개가 있음
1. addOperation BlockOperation 으로 바로 만들거나
2. Operation 객체를 상속 받은 아이를 사용

BlockOperation이란?

An operation that manages the concurrent execution of one or more blocks.

class BlockOperation : Operation

The BlockOperation class is a concrete subclass of Operation that manages the concurrent execution of one or more blocks. You can use this object to execute several blocks at once without having to create separate operation objects for each. When executing more than one block, the operation itself is considered finished only when all blocks have finished executing.

Blocks added to a block operation are dispatched with default priority to an appropriate work queue. The blocks themselves should not make any assumptions about the configuration of their execution environment.

레고 블락할 때 블락과 같은 걸로 이해 ..!

Class BlockOperation
iOS ) Operation실험
Swift – BlockOperation 사용하기

Q. 그래서 blockOperation을 어디에, 어떻게 넣어줘야 함?!!

let blockOperation = BlockOperation {
            for i in 1...10 {
                print(i)
            }
        }

A. 이렇게 하면 안됨.
for문 안에 1개의 operation 작업 단위 (업무 시작, 업무 끝)를 넣어줘서
고객 수 만큼 반복해주는 식으로 해줘야 한다!

blockOperation을 써줬을 때 문제점
→ 큐는 큐대로 돌아가고, 업무 마감 안내 문구 함수로 넘어가서 클로징 멘트가 작업 내용보다 먼저 출력이 되버림 ㅜㅜ (비동기로 작동하는 것처럼..)

결국 blockOperation 안쓰고 그냥 오퍼레이션 큐에 넣어줌

참고한 자료들

https://zeddios.tistory.com/512
https://zeddios.tistory.com/510
https://icksw.tistory.com/105
https://developer.apple.com/documentation/foundation/operationqueue/
https://developer.apple.com/documentation/foundation/operationqueue/1407971-waituntilalloperationsarefinishe
https://soooprmx.com/swift-blockoperation-사용하기/
https://thoonk.tistory.com/3

좋은 웹페이지 즐겨찾기