如何从SWITCH语句中访问主GUI线程?

时间:2017-05-04 14:15:58

标签: ios objective-c multithreading switch-statement

我需要从委托函数更新按钮的BG颜色,但是当我尝试从switch语句内部访问主线程时,我遇到了编译器错误。

代码如下

switch (peripheral.state) {
        case CBManagerStatePoweredOn:
            NSLog(@"Powered on");
            [peripheral startAdvertising:_beaconPeripheralData];
            dispatch_async(dispatch_get_main_queue(), ^{
                _adminPageExitBtn.backgroundColor = [UIColor greenColor];
            });
            break;
        case CBManagerStatePoweredOff:
            NSLog(@"Powered Off");
            [peripheral stopAdvertising];
            break;
        case CBManagerStateUnsupported:
            NSLog(@"Device not supported");
            break;
        default:
            break;
    }

错误信息如下

/Users/mdouhan/Documents/Documents - Mattias’s MacBook/NWMobileTill/NWMobileTill/AdminView.m:161:9: Cannot jump from switch statement to this case label
/Users/mdouhan/Documents/Documents - Mattias’s MacBook/NWMobileTill/NWMobileTill/AdminView.m:150:55: Jump enters lifetime of block which strongly captures a variable

如何从该委托方法正确更新按钮的BG颜色?

2 个答案:

答案 0 :(得分:1)

案例陈述中的范围很奇怪,根据C规范的定义。

或者更具体地说,case语句没有定义范围。范围由switch(){...}本身定义,案例实际上只是标准标签,其中交换机执行goto样式跳转到正确的标签。块声明的工作方式会干扰交换机的跳转行为。

最简洁的解决方法是简单地确保每个案例都有一个独特的范围:

switch (peripheral.state) {
        case CBManagerStatePoweredOn:
        {
            NSLog(@"Powered on");
            [peripheral startAdvertising:_beaconPeripheralData];
            dispatch_async(dispatch_get_main_queue(), ^{
                _adminPageExitBtn.backgroundColor = [UIColor greenColor];
            });
        }
            break;
        case CBManagerStatePoweredOff:
        {
            NSLog(@"Powered Off");
            [peripheral stopAdvertising];
        }
            break;
        case CBManagerStateUnsupported:
        {
            NSLog(@"Device not supported");
        }
            break;
        default:
            break;
    }

或者,或者,只是在每种情况下调用一个方法。 [self peripheralPoweredOn];[self peripheralPoweredOff];[self peripheralUnsupported];

这样,您不仅可以解决范围问题,而且可以让其他事情更容易驱动外围设备的状态而不仅仅是切换/案例处理。

答案 1 :(得分:0)

您的代码看起来是正确的。我的猜测是你的插座没有连接。

尝试在调用中添加NSLog语句:

switch (peripheral.state) {
  case CBManagerStatePoweredOn:
    NSLog(@"Powered on");
    [peripheral startAdvertising:_beaconPeripheralData];
    dispatch_async(dispatch_get_main_queue(), ^{
      //-------------------------------------------------
      //Add the line below
      NSLog("_adminPageExitBtn = %@", _adminPageExitBtn);
      //-------------------------------------------------
      _adminPageExitBtn.backgroundColor = [UIColor greenColor];
    });
    break;

...

如果显示nil,则需要在Interface Builder中连接插座。