Swift – BlockOperation 사용하기

Operation(NSOperation)은 특정한 작업을 수행하기 위한 코드와 데이터를 감싸는 객체로 해당 작업을 동기/비동기로 필요한 시점에 실행하기 위한 용도로 사용한다. NSOperation은 OSX 10.5에서도입되었는데, 이 시점의 Objective-C에서는 클래스의 외부에서 코드를 주입할 수 있는 언어적인 장치가 존재하지 않았기 때문에, 이를 사용하려면 무조건 NSOperation의 서브클래스를 만들어야 하는 불편한 점이 있었다. 따라서 간단한 코드 조각을 실행하기 위해서 NSOperation을 사용하는 것은 꽤나 불편한 일이었다.

OSX 10.6(스노우레퍼드)부터 GCC/Clang을 기본 컴파일러로 사용하게 되었고 이때부터 코드블럭 기능이 지원되었다. 즉 별도의 서브클래스를 작성하지 않더라도 코드 블럭의 형태로, 마치 클로저처럼 코드와 코드가 캡쳐링하는 데이터를 주입하여 오퍼레이션 인스턴스를 만드는 것이 가능해졌다. 실질적으로 NSOperation을 그대로 사용해야할 이유는 현재로서는 찾아보기 힘들다.

Swift – BlockOperation 사용하기 더보기

작업큐

작업 큐

때때로, 그리고 생각보다는 자주 프로그램은 한 번에 하나 이상의 일을 동시에 처리해야 하는 경우가 있다. 이러한 것 중 가장 중요한 것으로는 사용자의 입력에 대해서 반응하는 것이다. 그리고 그와 동시에 네트워크로 통신을 하거나, 대용량의 데이터를 읽거나 쓰고 혹은 데이터들을 처리하는 것을 동시에 진행한다.

앱의 최우선순위는 사용자에게 반응할 수 있게 하는 것이다. 어떤 장시간이 걸리는 일에 대해서 지속적으로 피드백이 주어진다면 사용자들은 그것을 기다릴 수 있다. 하지만 그렇지 않다면 (그래서 UI가 얼어버린 것으로 보인다면) 사용자들은 앱이 문제가 있거나 디바이스가 느리다고 인지하게 된다. 작업큐 더보기

NSOperation Tutorial in Swift

NSOperation in Swift

http://www.raywenderlich.com/76341/use-nsoperation-nsoperationqueue-swift

버튼을 탭하거나 텍스트 편집을 시작할 때 iOS/Mac앱이 반응을 멈추는 당혹스러운 경험을 해본적이 있을 것이다. Mac 앱이라면 마우스포인터(흔히 말하는 커서)가 형형색색의 비치볼로 변하는 것으로 지금 UI 반응을 할 수 없다는 것을 알려주는데, iOS앱에서는 이런 기제가 없으므로 사용자는 항상 UI에 반응할 수 있다고 기대하게 된다. 반응하지 않는 앱은 문제가 있거나 느리다고 느껴지고 리뷰에서 좋은 평가를 받기 힘들다.

앱이 항상 반응하도록 하는 것은 말처럼 쉽지 않다. 앱이 한가지 이상의 일을 동시에(사용자 터치에 반응하면서 다른 작업을 하는)해야 한다면 순식간에 여러가지 것들이 꼬이기 쉽다. 메인 런루프에서는 많은 작업을 처리할 시간이 없고 이는 오롯이 UI 반응에 집중해야 한다.

이제 불쌍한 개발자는 메인스레드에서 병렬작업으로 이행해야 한다. 병렬작업은 동시에 여러 개의 작업 스트림이 진행된다는 의미이며, 이를 통해 메인스레드는 항상 사용자의 터치에 반응하게 된다.

iOS에서 이런 작업을 수행하는 방법 중 하나는 NSOperation과 NSOperationQueue를 사용하는 것이다. 먼저 병렬작업을 사용하지 않은 앱을 만들어보자. 이 앱은 매우 버벅이고 느릴 것이다. 그리고 이 앱에 병렬작업을 추가하면 보다 반응이 좋은 UI를 제공하게 될 것이다. NSOperation Tutorial in Swift 더보기

[Objective C] 다중처리 큐와 오퍼레이션

다음은 큐와 오퍼레이션을 사용할 때 염두에 두어야 하는 사항들이다.

1

오퍼레이션은 기본적으로 이를 시작한 스레드에서 돌아간다. 만약 오퍼레이션이 비동기적으로 작업하기를 원한다면 오퍼레이션 큐를 사용하거나 NSOperation의 서브 클래스를 만들어서 별도의 스레드에서 시작하도록 해야 한다.

2

하나의 오퍼레이션은 다른 오퍼레이션이 작업을 완료하고나서 그 작업을 시작한다. 흔한 실수는 두 개의 오퍼레이션이 서로에 대해 의존하도록 만드는 것이다. 이렇게 되면 두 개의 오퍼레이션은 서로를 계속 기다리기만 하고 아무런 작업을 하지 못한다. 결국 메모리를 소진하고 앱이 죽을 수도 있다.

3

오퍼레이션은 취소될 수 있다. 따라서 NSOperation을 서브클래싱할 때는 isCanceled 변수의 값을 확인해서 작업을 시작하기 전에 취소 여부를 확인해야 한다. 예를 들어 인터넷 연결을 20초 동안 기다리는 작업이 있다고 하면, 작업을 시작할 때 이를 확인해서 취소한 작업이 시작되지 않도록 한다. 만약 긴 시간이 걸리는 작업의 경우에는 반복적으로 isCanceled의 값을 확인해서 중간에 중지할 수 있도록 하는게 좋다.

4

오퍼레이션 객체는 isFinished, isReady, isExecuting 등의 값에 대해 KVO가 적용되어야 한다. 이들 값을 변경할 때는 willChangeValueForKey: , didChangeValueForKey: 를 명시해준다.

5

NSOperation을 서브클래싱할 때는 main 메소드에 대해 별도의 오토릴리즈 풀을 만들어야 한다. (이는 단순히 @autorelease{…} 블럭 안에 코드를 쓰면 된다!) main 스레드는 프로그램의 메인 함수인 main과 유사하다. 실질적으로 오퍼레이션에 start 메시지를 보내면 오퍼레이션은 자신의 main 메소드를 호출한다.

6

항상 생성한 오퍼레이션 객체에 대해서 참조를 유지해야 한다. 한 번 큐에 들어간 오퍼레이션을 얻어오는 것은 불가능하다. 따라서 큐에 집어 넣기 이전에 참조를 만들어서 가지고 있어야 한다.

앱이 시작되는 지점은 메인 스레드이다. UI의 갱신은 항상 메인 스레드에서 일어나므로, 시간이 많이 걸리는 작업을 메인 스레드에서 하게되면 그 작업 동안은 UI가 반응이 없거나 매우 느린 것으로 표시된다. 이 경우에는 별도의 스레드를 만들어 그 작업을 진행해야 한다.(메인 스레드가 계속 UI와 반응할 수 있도록)