- 실행 중인 작업을 취소할 수 있는 능력
- 순서지정(의존성)
- 상태 체크(state machine)
- KVO notifications
- QoS수준
- completionBlock 제공
class SomeOperation: Operation {
var inputImage: UIImage?
var outputImage: UIImage?
override func main() {
// 정의할 메서드 내용
}
}
let op = SomeOperation
isReady
인스턴스화되어 실행할 준비가 되면, isReady 상태로 전환된다.
isExecuting
어느 시점에서 start 메서드가 호출하면, isExecuting 상태로 전환된다.
isCancelled
앱이 cancel 메서드를 호출하면, isCancelled 상태로 전환한 후 isFinished 상태로 전환된다.
isFinished
취소되지 않으면, isExecuting 상태에서 바로 isFinished 상태로 전환된다.
let operation = BlockOperation {
print("2 + 3" = \(2 + 3)")
}
operation.start
// 2 + 3 = 5
let sentence = "Ray's courses are the best!"
let operation = BlockOperation()
operation.addExecutionBlock {
print("Test")
}
for word in sentense.split(separator: " ") {
operation.addExecutionBlock {
print(word)
}
}
operation.strat
// Ray's
// Test
// courses
// are
// the
// best!
let sentence = "Ray’s courses are the best!"
let operation = BlockOperation()
operation.addExecutionBlock {
print("Test")
}
for word in sentence.split(separator: " ") {
operation.addExecutionBlock {
print(word)
sleep(2)
}
}
duration {
operation.start()
}
operation.completionBlock = {
print("End Job!")
}
import UIKit
class TiltShiftTableViewController: UITableViewController {
private let context = CIContext()
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 10
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "normal", for: indexPath) as! PhotoCell
cell.display(image: nil)
let name = "\(indexPath.row).png"
let inputImage = UIImage(named: name)!
print("Tilt shifting image \(name)")
guard let filter = TiltShiftFilter(image: inputImage, radius: 3),
let output = filter.outputImage else {
print("Failed to generate tilt shift image")
cell.display(image: nil)
return cell
}
print("Generating UIImage for \(name)")
let fromRect = CGRect(origin: .zero, size: inputImage.size)
guard let cgImage = context.createCGImage(output, from: fromRect) else {
print("No image generated")
cell.display(image: nil)
return cell
}
cell.display(image: UIImage(cgImage: cgImage))
print("Displaying \(name)")
return cell
}
}
import UIKit
final class TiltShiftOperation: Operation {
var outputImage: UIImage?
private let inputImage: UIImage
init(image: UIImage) {
inputImage = image
super.init()
}
}
private static let context = CIContext()
override func main() {
guard let filter = TiltShiftFilter(image: inputImage, radius: 3),
let output = filter.outputImage else {
print("Failed to generate tilt shift image")
return
}
let fromRect = CGRect(origin: .zero, size: inputImage.size)
guard let cgImage = TiltShiftOperation
.context
.createCGImage(output, from: fromRect) else {
print("No image generated")
return
}
outputImage = UIImage(cgImage: cgImage)
}
override func tableView(
_ tableView: UITableView,
cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "normal",
for: indexPath) as! PhotoCell
let image = UIImage(named: "\(indexPath.row).png")!
print("Filtering")
let op = TiltShiftOperation(image: image)
op.start()
cell.display(image: op.outputImage)
print("Done")
return cell
}
override func tableView(
_ tableView: UITableView,
cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "normal",
for: indexPath) as! PhotoCell
let image = UIImage(named: "\(indexPath.row).png")!
print("Filtering")
let op = TiltShiftOperation(image: image)
let queue = OperationQueue()
queue.addOperation(op)
let completion = BlockOperation {
cell.display(image: op.outputImage)
print("Done")
}
completion.addDependency(op)
OperationQueue.main.addOperation(completion)
return cell
}
TiltShiftOperation
을 시작하지 않고, OperationQueue
에 추가한다. BlockOperation
을 만들어 이전에 실행했던 코드를 completion
으로 추가하고, 이전 작업(op)이 끝나야 실행될 수 있도록 completion.addDependency(op)
를 추가한다. TiltShiftOperation
이 별도의 스레드에서 실행되어 테이블 뷰의 스크롤 동작과 상호작용하지 않기 때문이다. let op = TiltShiftOperation(image: image)
let queue = OperationQueue()
op.completionBlock = {
DispatchQueue.main.async {
cell.display(image: op.outputImage)
print("done")
}
}
queue.addOperation(op)
제가 학습한 내용을 요약하여 정리한 것입니다. 내용에 오류가 있을 수 있으며, 어떠한 피드백도 감사히 받겠습니다.
감사합니다.