setNeedsDisplay在块内不起作用

时间:2011-11-29 15:20:28

标签: ios objective-c-blocks setneedsdisplay

我正在使用CMMotionManager来检索加速度计数据。问题是加速度计数据会定期打印,实例变量会在视图中更改,但视图不会重新绘制。我已经检查过hv不是零并且所有内容都被挂钩了。在块中调用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];

    }];    
}

3 个答案:

答案 0 :(得分:12)

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

将此添加到您的块中:

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

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

答案 1 :(得分:4)

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

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

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

答案 2 :(得分:0)

只想测试@ cocoahero的答案。我试图在非主线程中调用setTitle来获取UIButton。标题确实改变了。我尝试使用Xcode 5.0.1定位iOS 5.1和7.0。我也从非主线程调用了setNeedsDisplay,它也起作用了。

[NSThread isMainThread]是我如何确保我的电话不是来自主线程的。我不确定从非主线程调用是导致问题的原因,但至少还有其他可能性。您可以查看my answer以了解其他问题。