CADisplaylink加入NSRunLoop后与performSelectorOnMainThread的执行顺序?

iOS三维多线程 怎样在每次调用CADisplaylink 函数之前 进行更新次线程的数据!

该回答引用ChatGPT

CADisplayLink是用于iOS中进行帧同步的一个类,常常用于动画和游戏开发中。它可以通过将自己加入到NSRunLoop中,实现在每一帧之前都会调用一个指定的方法。


在使用CADisplayLink的时候,可以将其添加到NSRunLoop中,让其在RunLoop的特定模式下执行。此时,在主线程中会同时执行RunLoop中的其他任务,包括performSelectorOnMainThread方法。因此,执行顺序可能是不确定的,取决于RunLoop中其他任务的情况。


如果需要在每次调用CADisplayLink之前更新次线程的数据,可以在另一个线程中进行数据的计算和准备,然后在CADisplayLink回调方法中使用这些数据。具体实现方法如下:

  • 在另一个线程中进行数据的计算和准备,可以使用GCD或者NSOperationQueue等多线程技术实现。
  • 在CADisplayLink的回调方法中使用已经准备好的数据,更新界面。为了确保数据的准确性,可以使用线程同步技术,如NSLock或者dispatch_semaphore等,保证数据的一致性。
  • 在每次更新界面之后,将新的数据发送给另一个线程进行计算和准备,以便下一次调用CADisplayLink时使用。

下面是一个示例代码,演示如何在使用CADisplayLink时进行多线程数据更新的方法:

//在主线程中初始化CADisplayLink
CADisplayLink *displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(displayLinkCallback)];
[displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];

//在另一个线程中进行数据的计算和准备
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    while (YES) {
        //计算和准备数据
        [self prepareData];
    }
});

//CADisplayLink的回调方法,更新界面
- (void)displayLinkCallback {
    //获取已经准备好的数据
    id data = [self getData];
    
    //更新界面
    [self updateUIWithData:data];
    
    //发送新的数据到另一个线程进行计算和准备
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        //计算和准备数据
        [self prepareData];
    });
}

在这个示例代码中,prepareData方法用于计算和准备数据,getData方法用于获取已经准备好的数据,updateUIWithData方法用于更新界面。注意,在使用多线程时,要确保数据的一致性,防止出现数据竞争等问题。