How to wait in NSThread until some event occur in iOS?

前端 未结 3 1039
野性不改
野性不改 2021-02-14 10:10

How to wait inside the NSThread until some event occur in iOS?

eg, We created a NSThread and started a thread loop. Inside the thread loop, there is condition to check w

3条回答
  •  别跟我提以往
    2021-02-14 11:01

    You could use run loop sources. In essence:

    1) On secondary worker thread create and install run loop source, and pass it somehow, along with worker thread run loop reference, to other managing thread which will be sending messages to this one:

        CFRunLoopSourceContext context = {0, self, NULL, NULL, NULL, NULL, NULL,
                                        &RunLoopSourceScheduleRoutine,
                                        RunLoopSourceCancelRoutine,
                                        RunLoopSourcePerformRoutine};
        CFRunLoopSourceRef runLoopSource = CFRunLoopSourceCreate(NULL, 0, &context);
        CFRunLoopRef runLoop = CFRunLoopGetCurrent();
        CFRunLoopAddSource(runLoop, runLoopSource, kCFRunLoopDefaultMode);
        // Pass runLoopSource and runLoop to managing thread
    

    Here there are custom routines mentioned above - you are responsible to provide them:

        RunLoopSourceScheduleRoutine - called when you install run loop source (more precisely, when you call CFRunLoopAddSource)
    
        RunLoopSourceCancelRoutine - called when you remove run loop source (more precisely, when you call CFRunLoopSourceInvalidate)
    
        RunLoopSourcePerformRoutine - called when run loop source was signaled (received a message from manager thread) and this is a place where you should perform a job
    

    2) On worker thread, start usual run loop, something similar to this:

        BOOL done = NO;
        do {
            int result = CFRunLoopRunInMode(kCFRunLoopDefaultMode, 10, YES);
            done = (result == kCFRunLoopRunStopped) || (result == kCFRunLoopRunFinished);
        } while (!done); 
    

    3) Now, on managing thread you could signal (send message) to previously received run loop source when needed (and wake up the run loop of those thread in case it is asleep):

        CFRunLoopSourceSignal(runLoopSource);
        CFRunLoopWakeUp(workerThreadRunLoop);
    

    More details are in Apple's guide.

提交回复
热议问题