最后一次调用结束后旋转罗盘

做了一个罗盘,每5度旋转。问题是,在用户旋转超过五度时,我会同时收到多条服务响应,然后选择方法也会被多次调用。在最后一次调用没结束之前,罗盘旋转非常迟钝。

在最后一次待用结束后,怎么旋转罗盘?

- (void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading
{
    if (newHeading.headingAccuracy > 0) {
       /* Rotate the compass to the selected degree */
       [UIView animateWithDuration:1.0f animations:^{
           [self.compassImageView rotateByDegree:degree clockWise:YES];
       }];
    }
}

要在最后一次待用结束后旋转罗盘,可以使用一种叫做信号量的线程同步机制。


信号量是一种计数器,可用于限制线程访问某些资源的数量。例如,如果某个资源的信号量计数器为1,则只允许一个线程访问该资源。当线程完成对资源的访问时,可以递增信号量计数器,以便其他线程可以访问该资源。


使用信号量可以在最后一次待用结束后旋转罗盘。首先,你需要在你的类中声明一个信号量计数器,例如:

dispatch_semaphore_t semaphore;

然后在你的方法开始时初始化信号量计数器:

semaphore = dispatch_semaphore_create(0);

在你的方法最后,调用dispatch_semaphore_signal函数,来递增信号量计数器,告诉其他线程可以开始执行了。

dispatch_semaphore_signal(semaphore);

然后在你的didUpdateHeading方法中,在开始时调用dispatch_semaphore_wait函数,等待信号量计数器被递增。这样,在最后一次待用结束后,didUpdateHeading方法才会开始执行,然后你就可以旋转罗盘了。


举个例子,假设你想要在最后一次待用结束后旋转罗盘。你可以在didUpdateHeading方法中使用以下代码来实现:

- (void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading
{
    // 等待信号量计数器被递增
    dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
    
    if (newHeading.headingAccuracy > 0) {
       /* Rotate the compass to the selected degree */
       [UIView animateWithDuration:1.0f animations:^{
           [self.compassImageView rotateByDegree:degree clockWise:YES];
       }];
    }
}

在你的方法结束时,调用dispatch_semaphore_signal函数,来递增信号量计数器,告诉didUpdateHeading方法可以开始执行了。

- (void)someMethod
{
    // 在方法开始时初始化信号量计数器
    semaphore = dispatch_semaphore_create(0);

    // 执行一些操作

    // 在方法结束时递增信号量计数器
    dispatch_semaphore_signal(semaphore);
}

这样,在最后一次待用结束后,didUpdateHeading方法就会开始执行,然后你就可以旋转罗盘了。