iOS 개발을 하면서 스레드를 직접 생성해서 해야하는 작업은 별로 없었다.
DispatchQueue, OperationQueue 를 이용해 대부분의 작업을 할 수 있지만
특정 하나의 스레드에서만 작업되기를 원한다면 스레드를 직접 생성해서 해당 스레드에서 작업이 되도록 해야 한다.
앱내에서 Realm 관련 작업을 했는데 해당 모델의 Read/Write 가 하나의 스레드에서 되어야 해서
특정 스레드를 생성해서 작업해야 했다.
다음은 스레드를 생성하고 작업대상을 추가하여 생성된 스레드에서만 작업이 되는 간단한 예시이다.
let t = CustomThread() for i in 0 ..< 5 { t.push(Entry(index: i)) } DispatchQueue.global().async { for i in 5 ..< 10 { t.push(Entry(index: i)) } }
// 스레드가 처리할 엔트리 class Entry { private var index = 0 init(index: Int) { self.index = index } func work() { print("working, entry index \(index) thread \(Thread.current)") } }
스레드가 처리할 엔트리를 넣을때와 실제 작업을 하기 위해 엔트리를 뺄 때
condition 객체를 이용하여 엔트리를 넣는 스레드와 엔트리를 빼는 스레드(CustomThread) 동시 접근을 막는다.
class CustomThread { private var serialQueue = DispatchQueue(label: "SerialQueue") private var thread: Thread! private var condition = NSCondition() private var entries = [Entry]() init() { thread = Thread(target: self, selector: #selector(self.main(_:)), object: nil) thread.start() } @objc func main(_ param: Any?) { while !Thread.current.isCancelled { condition.lock() if entries.isEmpty { condition.wait() } for entry in entries { entry.work() } entries.removeAll() condition.unlock() } } func push(_ entry: Entry) { func push() { condition.lock() entries.append(entry) condition.signal() condition.unlock() } serialQueue.async { push() } } }
결과는 아래와 같다. 0~4 인덱스는 메인스레드에서 넣고 5~9 인덱스는 임의의 작업 스레드에서 넣었는데
실제 작업은 모두 하나의 스레드에서 한개씩 이루어 지는 것을 알 수 있다.
working, entry index 0 thread <NSThread: 0x600000376ec0>{number = 7, name = (null)} working, entry index 1 thread <NSThread: 0x600000376ec0>{number = 7, name = (null)} working, entry index 2 thread <NSThread: 0x600000376ec0>{number = 7, name = (null)} working, entry index 3 thread <NSThread: 0x600000376ec0>{number = 7, name = (null)} working, entry index 4 thread <NSThread: 0x600000376ec0>{number = 7, name = (null)} working, entry index 5 thread <NSThread: 0x600000376ec0>{number = 7, name = (null)} working, entry index 6 thread <NSThread: 0x600000376ec0>{number = 7, name = (null)} working, entry index 7 thread <NSThread: 0x600000376ec0>{number = 7, name = (null)} working, entry index 8 thread <NSThread: 0x600000376ec0>{number = 7, name = (null)} working, entry index 9 thread <NSThread: 0x600000376ec0>{number = 7, name = (null)}
One thought on “Swift Thread 사용해 보기”
포스팅 잘 보고 갑니다~!