3

Crashes when the class is destructed, how to handle unfinished semaphore?

class CrashTestViewCtrl: UIViewController {

    private var semaphore = DispatchSemaphore(value: 2)

    override func viewDidLoad() {
        super.viewDidLoad()
        
        DispatchQueue.global().async { [weak self] in
            self?.semaphore.wait()
            // do something ......
        }
    }
    
    deinit {
        print("……deinit……")
    }
}

EXC_BAD_INSTRUCTION

aheze
  • 24,434
  • 8
  • 68
  • 125

1 Answers1

0

It crashes because of lack of semaphore.signal() and wrong setup of semaphore.

You should call semaphore.signal() after you are done with the async method.

You should add semaphore.wait() outside of the async method.

In your case, it could be like this;

class CrashTestViewCtrl: UIViewController {

private var semaphore = DispatchSemaphore(value: 2)

override func viewDidLoad() {
    super.viewDidLoad()
    
    DispatchQueue.global().async { [weak self] in
        
        // do something ......
        self?.semaphore.signal()
    }
    
    semaphore.wait()
}

deinit {
    print("……deinit……")
}

}
musakokcen
  • 359
  • 2
  • 12
  • Thank you. In your code. I poped the viewController before I can call `self?. semaphor.signal ()`, crashed too. – 醉翁之意 May 28 '21 at 01:45
  • if it is deinitialized before you call ".signal()", it crashed. you should make sure that you call "signal()" before it falls deinit {} – musakokcen May 28 '21 at 06:33
  • No, you should not move `wait` call outside of the async method. You have completely misunderstood the point of the `wait` ... `signal` pattern _inside_ the asynchronous closure. This pattern is for constraining degree of concurrency without blocking the main thread. You have replaced this with the classic example of the abuse of semaphores to make something asynchronous behave synchronously, which does block the main thread. Sure, you'll see your pattern littered about on StackOverflow, but, in short, you're replaced the OP’s code with a classic example of what one should not do. – Rob Dec 23 '21 at 06:44