在辅助队列中执行UI更新

时间:2012-07-31 01:15:41

标签: iphone objective-c

我正在使用新的CoreMotion框架来监控一些硬件设备。以下是执行此操作的典型代码:

-(void)startAccelerometer{
self.motion.accelerometerUpdateInterval = 1/30.0f;
NSOperationQueue* accelerometerQueue = [[NSOperationQueue alloc] init];
CMAccelerometerHandler accelerometerHandler = ^(CMAccelerometerData *accelerometerData, NSError *error) {

    NSLog(@"Accelerometer realtime values");
    NSLog(@"x=%f", accelerometerData.acceleration.x);
    NSLog(@"y=%f", accelerometerData.acceleration.y);
    NSLog(@"z=%f", accelerometerData.acceleration.z);
    NSLog(@"  ");

};
[self.motion startAccelerometerUpdatesToQueue:accelerometerQueue withHandler:[[accelerometerHandler copy]autorelease]];

}

这很好用。现在我想在UILabel上打印这些值,但由于CoreMotion框架使用了块,因此不能保证它在主队列中(事实上不适用于我的应用程序)。像这样在主队列上运行标签的setter是“错误的”吗?

-(void)startAccelerometer{
self.motion.accelerometerUpdateInterval = 1/30.0f;
NSOperationQueue* accelerometerQueue = [[NSOperationQueue alloc] init];
CMAccelerometerHandler accelerometerHandler = ^(CMAccelerometerData *accelerometerData, NSError *error) {
    dispatch_async(dispatch_get_main_queue(), ^{
        self.lblAccelerometer.text = [NSString stringWithFormat:@"Accelerometer:\nx = %f\ny = %f\nz = %f",
                                      accelerometerData.acceleration.x,
                                      accelerometerData.acceleration.y,
                                      accelerometerData.acceleration.z];

    });

};
[self.motion startAccelerometerUpdatesToQueue:accelerometerQueue withHandler:[[accelerometerHandler copy]autorelease]];

}

它运作得很好,我真的没有看到任何理由为什么这会不受欢迎。有什么想法?

2 个答案:

答案 0 :(得分:1)

这是我在许多项目中使用的常用方法。 UI更新必须在主线程上进行。

//Dispatch on background thread
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

    //background processing goes here

    //Dispatch on main thread
    dispatch_async(dispatch_get_main_queue(), ^{
            //update UI here
    });
});

在您的情况下,您的UI更新正在主线程上进行。所以我不担心改变什么。

答案 1 :(得分:0)

你很容易理解块的概念,简单来说就是这样:

块是一小段代码,可以作为变量处理,并在特定时间或线程执行。

所有UI更新必须在主线程上执行,所以只要你这样做就可以了。

代码可以在具有不同优先级的不同线程中以同步或异步模式执行。在你的代码上你做得非常好,你不仅要将它发送到主队列,这是uiupdates应该执行的地方,但是你也调度async,这是更新发送到主队列的最安全的方法(从你的代码我无法判断您是从主队列还是辅助队列运行此特定代码段,但如果您要将主队列中的同步块分派到主队列,则程序将停止工作)

对于iOS文档:

  

使用dispatch_get_main_queue函数获取串行调度   与应用程序主线程关联的队列。这个队列是   为Cocoa应用程序和应用程序自动创建   调用dispatch_main函数或配置运行循环(使用   主要是CFRunLoopRef类型或NSRunLoop对象   线程。

请在此处阅读http://developer.apple.com/library/ios/#documentation/General/Conceptual/ConcurrencyProgrammingGuide/OperationQueues/OperationQueues.html#//apple_ref/doc/uid/TP40008091-CH102-SW1