728x90
반응형
안녕하세요! 후르륵짭짭입니다.
하,,, 정말 블로그 쉽지 않네요 ㅠㅠ
일도 해야하고, 공부도 해야하고, 쉬기도 해야하는데 ㅠㅠ
블로그 작성 까지 하려니 쉽지 않습니다.
점점 블로그 퀄리티가 나빠지는 것 같은데, 이해 좀 부탁드리겠습니다.
** 단순한 BlockOpeation **
//it will block the main thread since operation.start() was called on main thread
//Operation objects execute in a synchronous manner by default
let operatoin = BlockOperation {
for i in 0...10 {
print("hello \(i)")
print(Unmanaged.passUnretained(Thread.current).toOpaque())
print(Thread.isMainThread)
}
}
operatoin.start()
현재 opeation은 메인 Thread에 있으니 Main Thread 위에서 작업하게 됩니다.
즉 start()가 호출 되는 시점의 Thread에서 블록오퍼레이션이 작업 할 겁니다.
** 전체는 순차적으로! 내부는 비동기적으로 **
//Operation의 ExecuteBlock 자체들은 비동기적으로 작동하지만
//Operation 외부의 것은 동기적으로 작동한다.
//따라서 BlockOperation이 끝나야 다음 작업을 시작한다.
let ourOperation = BlockOperation()
ourOperation.addExecutionBlock {
for i in 0...10{
print("Hello\(i)")
}
}
ourOperation.addExecutionBlock {
for i in 0...10{
print("World\(i)")
}
}
ourOperation.addExecutionBlock {
for i in 0...10{
print("짭짭\(i)")
}
}
ourOperation.start()
print("This will called when 'Hello' and 'World' executed")
for i in 0..<10{
print("End\(i)")
}
ourOperation을 생성하고 작업들을 생성해주고 start()를 해줬습니다.
이렇게 해주면 내부적으로는 비동기적으로 작업하지만
외부적으로는 순차적으로 작업하게 되어
BlockOperation => This will called ,,,, => End(0~9)
이렇게 순차적으로 수행 됩니다.
** 그럼 비동기적으로 수행하자 **
//이렇게 다른 쓰레드로 할 경우
//비동기적으로 작업을 할 수 있게 한다.
//하지만 같은 쓰레드에 있는 것은
//동기화 작업을 하게 된다.
let ourOperationOtherThread = BlockOperation()
ourOperationOtherThread.addExecutionBlock {
for i in 0 ... 10 {print("Hello \(i)")}
}
ourOperationOtherThread.addExecutionBlock {
for i in 0 ... 10 {print("짭짭 \(i)")}
}
DispatchQueue.global(qos: .background).async {
print("Running on Thread : \(Thread.current)")
ourOperationOtherThread.start()
print("ourOperationOtherThread.start() \(Thread.current) will block me please help")
for i in 0..<10{
print("End\(i)")
}
}
print("This will called now")
** CompletionBlock으로 작업 마칠 때를 알자 **
//completion block을 추가해서
//언제 Operation이 끝나는지 추론할 수 있다.
let ourOperationCompletionBlock = BlockOperation()
ourOperationCompletionBlock.name = "Hello짭짭"
ourOperationCompletionBlock.completionBlock = {
print("Finished on Thread : \(Thread.current)")
}
ourOperationCompletionBlock.addExecutionBlock {
for i in 0 ... 10 {print("Hello \(i)")}
}
ourOperationCompletionBlock.addExecutionBlock {
for i in 0 ... 10 {print("짭짭 \(i)")}
}
DispatchQueue.global(qos: .background).async {
print("Running on Thread : \(Thread.current)")
ourOperationCompletionBlock.start()
}
print("This will called now \(Thread.current) \(Thread.isMainThread)")
** DispatchQueue없이 BlockOperaton을 비동기적으로 작업하게 하기 **
//BlockOperation을 비동기적으로 작업하기 위해서는
//아래 처럼 Thread를 새롭게 생성한 다음 해주면 된다.
let operation = BlockOperation {
for i in 0 ... 5 {
print("hello \(i)")
print(Unmanaged.passUnretained(Thread.current).toOpaque())
print(Thread.isMainThread)
}
}
let thread = Thread(block: {
operation.start()
})
thread.start()
print("Thraed Start")
** 비동기적으로 수행 - Operation으로 나만의 구조화된 Task를 생성하자 **
//MyOperation을 만들고
//main을 overrid하면
//동기적으로 Operation을 하는 객체를 만들 수 있다.
//그리고 start를 통해 수행시킨다.
class MyOpertaion : Operation {
override func main() {
for i in 0 ... 10 {
print("hello \(i)")
print(Unmanaged.passUnretained(Thread.current).toOpaque())
print(Thread.isMainThread)
}
}
}
let operation = MyOpertaion()
operation.start()
print("Operation Start")
** 비동기적으로 수행 - Opeation으로 구조화된 Task를 생성하자 - 2 **
//나만의 Thread를 만들어서
//비동기적으로 작업을 할 수 있다.
//operation cancel을 하면 작업을 멈춘다.
//모든 작업은 start 이후에
//main에서 본격적인 작업을 하게 된다.
class MyConcurrentQueue : Operation {
override func start() {
if isCancelled {return}
Thread.init(block: main).start()
}
override func main() {
for i in 0 ... 9000 {
if isCancelled {break}
print("hello \(i) isCanclled : \(isCancelled) \n \(Unmanaged.passUnretained(Thread.current).toOpaque()) \n \(Thread.isMainThread)")
}
}
}
let operation = MyConcurrentQueue()
operation.start()
for i in 0...100 {
print("짭짭 \(i)")
if i == 100 {
operation.cancel()
}
}
** 비동기적으로 수행 - OperationQueue로 구조화된 작업을 사용성 높게 만들자 **
//Operation Queue를 사용하면
//위에서 한 것 처럼 Thread를 나눠서 비동기작업을 할 필요가 없다.
//addOperation을 해주면 작동한다.
let operationQueue = OperationQueue()
let blockOperatoin1 = BlockOperation(block: {
for i in 0...10{
print("Hello \(i) Thread : \(Thread.isMainThread)")
}
})
let blockOperation2 = BlockOperation(block: {
for i in 0...10{
print("짭짭 \(i) Thread : \(Thread.isMainThread)")
}
})
operationQueue.addOperation(blockOperatoin1)
operationQueue.addOperation(blockOperation2)
for i in 0...10 {
print("End \(i) Thread : \(Thread.isMainThread)")
}
** 비동기적으로 수행 - OpeartionQueue를 순차적으로 수행하게 하자 **
//OperationQueue를 Serial 하게 작업하고 싶을 때
let operationQueue = OperationQueue()
let blockOperatoin1 = BlockOperation(block: {
for i in 0...10{
print("Hello \(i) Thread : \(Thread.isMainThread)")
}
})
let blockOperation2 = BlockOperation(block: {
for i in 0...10{
print("짭짭 \(i) Thread : \(Thread.isMainThread)")
}
})
//maxConcurrentOperationCount의 숫자를 1로 해준다.
//The maximum number of queued operations that can execute at the same time.
//The default value is -1 which means let the system decide
operationQueue.maxConcurrentOperationCount = 1
operationQueue.addOperation(blockOperatoin1)
operationQueue.addOperation(blockOperation2)
for i in 0...10 {
print("End \(i) Thread : \(Thread.isMainThread)")
}
** Opeation의 순서를 정해주자 **
//각각의 Operation에 Dependency를 걸어서
//해당 작업이 끝나고 나서 Operation을 수행하게 만들 수 있다.
let operationQueue = OperationQueue()
let blockOperation1 = BlockOperation(block: {
for i in 0...10{
print("Hello \(i) Thread : \(Thread.isMainThread)")
}
})
let blockOperation2 = BlockOperation(block: {
for i in 0...10{
print("짭짭 \(i) Thread : \(Thread.isMainThread)")
}
})
let blockOperation3 = BlockOperation(block: {
for i in 0...10{
print("End \(i) Thread : \(Thread.isMainThread)")
}
})
//맥스를 두개를 주더라도 순서를 맞추게 된다.
operationQueue.maxConcurrentOperationCount = 2
blockOperation1.addDependency(blockOperation2)
blockOperation3.addDependency(blockOperation1)
operationQueue.addOperation(blockOperation1)
operationQueue.addOperation(blockOperation2)
operationQueue.addOperation(blockOperation3)
** OperationQueue로 DispatchGroup을 만들어 보자 **
//Dependency를 통해서 DispatchGroup을 직접 구현 할 수 있다.
let operationQueue = OperationQueue()
let helloblockOperation = BlockOperation {
for i in 0...10 {
print("Hello \(i)")
}
}
let endBlockOperation = BlockOperation {
for i in 0...10 {
print("End \(i)")
}
}
let worldBlockOperation = BlockOperation{
for i in 0...10{
print("World \(i)")
}
}
//모든 작업이 완료가 되고 나서 불릴 작업
let completeBlockOperation = BlockOperation{
print("All Operation is Compelted")
}
operationQueue.maxConcurrentOperationCount = 4
completeBlockOperation.addDependency(helloblockOperation)
completeBlockOperation.addDependency(worldBlockOperation)
completeBlockOperation.addDependency(endBlockOperation)
//waitUntilFinished -> False = Main Task와 비동기적으로 작업한다.
//waitUntilFinished -> true = 해당 작업이 모두 끝나고 나서 Main Task를 작업 하도록 한다.
operationQueue.addOperations([helloblockOperation,worldBlockOperation,endBlockOperation,completeBlockOperation], waitUntilFinished: false)
for i in 0...10{
print("Main Thread is Worked \(i)")
}
** OperationQueue로 DispatchGroup을 만들어 보자2 **
//waitUntilFinished만들 통해서 dependency 추가 없이 DispatchGroup을 사용할 수 있다.
DispatchQueue.global().async {
let operationQueue = OperationQueue()
let helloblockOperation = BlockOperation {
for i in 0...10 {
print("Hello \(i)")
}
}
let endBlockOperation = BlockOperation {
for i in 0...10 {
print("End \(i)")
}
}
let worldBlockOperation = BlockOperation{
for i in 0...10{
print("World \(i)")
}
}
operationQueue.maxConcurrentOperationCount = 4
operationQueue.addOperations([helloblockOperation,worldBlockOperation,endBlockOperation], waitUntilFinished: true)
print("All Task Finished Dispatch Group same")
}
for i in 0...50{
print("Main Thread is Worked \(i)")
}
참고사이트 :
https://zeddios.tistory.com/510
https://ios-development.tistory.com/799
728x90
반응형
'Xcode > Swift - PlayGround' 카테고리의 다른 글
PlayGround) RxSwift-Error Handle (0) | 2022.02.07 |
---|---|
PlayGround) Operation Queue - 2 (0) | 2022.01.17 |
PlayGround) URLSessionDownload를 이용해서 PDF 파일 다운로드 (0) | 2021.12.26 |
PlayGround)Enum의 활용 (0) | 2021.09.22 |
PlayGround) Notification Center의 사용법 (0) | 2021.09.03 |
댓글