티스토리 뷰

얼마전 스승님과 "1주일에 1번씩 블로그 포스팅을 할 수 있도록 노력해보겠다."는 약속을 하였습니다.

그동안 공부하며 기능적인 내용들보다는 되게 많이 고민하고, 개인적으로 어렵다 느꼈던 내용들을 위주로 정리해 두려 합니다.

 

22년 첫번째 포스트 주제! 바로 GCD!!! ( 비동기로 하나의 데이터를 작업할 때 사용법 )

얼마 전 API주소의 이미지들을 URLSession을 사용하여 가져오고, 이를 이미지배열에 하나씩 넣고 있었습니다. 

근데 갑자기 쓰레드에서 오류가 나면서 이미지가 안들어 오더군요..

 

 

 

오류가 난 이유가 비동기로 실행되는 작업들은 각각 다른 쓰레드에서 실행이 되고 (1번 쓰레드의 작업이 빨리 끝난다면 해당 쓰레드가 재활용 될 수 있음 ) 만약 작업내용이 하나의 자원에 접근하고 있다면!?

class ViewController: UIViewController {
    var strings: [String] = []
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        for i in 0 ..< 100{
            DispatchQueue.global().async  {
                self.taskingAsync(append: "\(i)")
            }
        }
    }
    
    func taskingAsync(append value: String){
        strings.append(value)
        print("task \(value)")
    }
}

 

 * 하나의 자원 strings

 

오류가..납니다.. 작업한 쓰레드들이 나오고, 오류가 난 쓰레드를 보여줍니다. ( 경쟁상태 == 레이스컨디션 )

strings.append()구문에서 오류가 났네요.

 

이는 여러 쓰레드가 하나의 자원을 선점하려 나는 오류입니다! 그럼 어떻게 해결해야 할까요?

 

func taskingAsync(append value: String){
    DispatchQueue.main.async {
        self.strings.append(value)
        print("task \(value)")
    }
}

DispatchQueue.main.async로 감싸주었습니다.

오류가 해결된 이유! 즉 DispatchQueue.main.async블록 안에 선언한 이유입니다.

Thread1, Thread3, Thread5번이 동시에 작업이 끝나 strings.append를 3개의 쓰레드가 동시에 사용 시도하여 났던 오류였으니

strings만 담는 쓰레드를 직접 지정해주었습니다.

DispatchQueue.main.async가 작업이 들어오는대로 큐에 담아 두었다가, 순차적으로 담아주는 역할을 해 주었기에 오류가 해결된 것입니다!

스위프트에서 쓰레드를 직접 지정할 수 있는 경우는 main밖에 없기에 메인을 사용하여 이를 해결하였습니다.

틀린내용이 있다면 언제든 말씀해주세요! 

감사합니다!

 

 

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
글 보관함