7

CMMotionManager用于检索加速度计数据。问题是加速度计数据会定期打印,视图中的实例变量会更改,但视图不会重绘。我检查过hv它不是 nil 并且一切都被钩住了。在块内调用 setNeedsDisplay 有问题吗?

-(void) viewDidAppear:(BOOL) animated
{
    [super viewDidAppear: animated];

    [motionManager startAccelerometerUpdatesToQueue:motionQueue withHandler:
     ^(CMAccelerometerData *accelerometerData, NSError *error)
    {

        NSLog(@"%@",accelerometerData);

        HypnosisView *hv = (HypnosisView *) [self view];

        hv.xShift = 10.0 * accelerometerData.acceleration.x;
        hv.yShift = -10.0 * accelerometerData.acceleration.y;

        [hv setNeedsDisplay];

    }];    
}
4

3 回答 3

12

这是因为您在与主线程不同的线程上调用 UI 方法。

将此添加到您的块中:

dispatch_async(dispatch_get_main_queue(), ^{
    [hv setNeedsDisplay];
});

请记住,任何处理用户界面元素的方法都必须从主线程中调用。

于 2011-11-29T15:36:52.830 回答
4

我在其他块中也做了同样的事情,它确实有效,但不是你在这里使用的回调。也许该块没有在主线程上执行?您可以通过以下方式检查:

NSLog(@"Main thread? %d", [NSThread isMainThread]);

如果不是,您可以强制setNeedsDisplay在主线程上运行。

于 2011-11-29T15:36:33.500 回答
0

只是想测试@cocoahero 的答案。我试图setTitle在非主线程中调用 UIButton。并且标题确实改变了。我尝试使用 Xcode 5.0.1 针对 iOS 5.1 和 7.0 进行此操作。setNeedsDisplay我也从非主线程调用,它也有效。

[NSThread isMainThread]是我如何确保我的调用不是来自主线程的。我不确定从非主线程调用是导致您的问题的原因,但至少还有其他可能性。你可以看看对另一个问题的回答。

于 2013-11-03T07:56:09.030 回答