【问题标题】:setNeedsDisplay not working inside a blocksetNeedsDisplay 在块内不起作用
【发布时间】:2011-11-29 15:20:28
【问题描述】:

我正在使用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];

    }];    
}

【问题讨论】:

    标签: ios objective-c-blocks setneedsdisplay


    【解决方案1】:

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

    将此添加到您的块中:

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

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

    【讨论】:

    • 感谢解决方案。作为一个局外人,在这里有知识渊博的人真是太好了。
    【解决方案2】:

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

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

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

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-03-20
        • 1970-01-01
        相关资源
        最近更新 更多