Xcode中块外变量的问题

时间:2018-04-03 21:53:57

标签: ios xcode

我基本上尝试将URL分配给Content.link个案例,我将从一个块中的文件加载(getWebData)。

我知道该部分正在运行,因为我可以在日志中看到它,但我不明白为什么当我通过self getWebData:^(NSArray *arrValue)

呼叫时,我在这个块中无法使用这些值

在下面的示例中,它有效,因为我已经通过NSString *WebsiteLink1 = @"http://link1";手动设置了每个,但是一旦我发表评论,我就会得到Use of undeclared identifier 'WebsiteLink1'

我不明白为什么它不起作用。

- (IBAction)ShowContent:(id)sender
    {
        Content = [self.storyboard instantiateViewControllerWithIdentifier:@"Content"];

        [self getWebData:^(NSArray *arrValue)
         {
         NSString *WebsiteLink1 = arrValue[0];
         NSString *WebsiteLink2 = arrValue[1];
         NSString *WebsiteLink3 = arrValue[2];
         }
     ];
    NSString *WebsiteLink1 = @"http://link1";
    NSString *WebsiteLink2 = @"http://link2";
    NSString *WebsiteLink3 = @"http://link3";

    switch ([sender tag])
    {
        case 1:
            Content.link = WebsiteLink1;
            break;
        case 2:
            Content.link = WebsiteLink2;
            break;
        case 3:
            Content.link = WebsiteLink3;
            break;

        default:
            break;
    }

    lastViewController = Content;
    [self.navigationController pushViewController:Content animated:YES];
}

我的理解是,这是应该调用块getWebData并使数组变量可用的部分,但它没有这样做(没有错误显示)。

  [self getWebData:^(NSArray *arrValue)
             {
             NSString *WebsiteLink1 = arrValue[0];
             NSString *WebsiteLink2 = arrValue[1];
             NSString *WebsiteLink3 = arrValue[2];
             }
         ];

getWebData的代码在这里:

typedef void(^CallbackBlock)(id value);

- (void)getWebData:(CallbackBlock)callback
{
    NSURLSessionConfiguration *sessionConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration];
    NSURLSession *session = [NSURLSession sessionWithConfiguration:sessionConfiguration];
    NSURLRequest *urlRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://webdata.dat"]];

    [[session dataTaskWithRequest:urlRequest completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {

        if (data != nil && !error)
        {
            NSString *string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
            NSLog(@"Full WebLinks%@", string);
            NSArray *arrValue = [string componentsSeparatedByString:@","];
            NSMutableArray *arrInfo = [NSMutableArray array];
            dispatch_async(dispatch_get_main_queue(), ^{
                NSString *WebsiteLink1 = arrValue[0];
                NSLog(@"WebsiteLink1 : %@", WebsiteLink1);
                NSString *WebsiteLink2 = arrValue[1];
                NSLog(@"WebsiteLink2 : %@", WebsiteLink2);
                NSString *WebsiteLink3 = arrValue[2];
                NSLog(@"WebsiteLink3 : %@", WebsiteLink3);
            });
        }
        else
        {
            NSLog(@"%@", error.debugDescription);
        }
    }] resume];
}

1 个答案:

答案 0 :(得分:0)

问题是这里声明了这3个变量

NSString *WebsiteLink1 = arrValue[0];
NSString *WebsiteLink2 = arrValue[1];
NSString *WebsiteLink3 = arrValue[2];

属于块的范围,意味着您无法访问其中任何一个,因为它们不存在于外部scrope中(IBAction方法范围)

因此您可以使用完成处理程序或移动块内的所有底部代码,旁边的部分代码(调用getWebData的那个)是异步,因此您不应该运行代码这个开关代码将在你从网络电话获得数据之前运行,重构就像这样

- (IBAction)ShowContent:(id)sender
{
    Content = [self.storyboard instantiateViewControllerWithIdentifier:@"Content"];

    [self getWebData:^(NSArray *arrValue)
     {
        NSString *WebsiteLink1 = arrValue[0];
        NSString *WebsiteLink2 = arrValue[1];
        NSString *WebsiteLink3 = arrValue[2];

       switch ([sender tag])
       {
         case 1:
           Content.link = WebsiteLink1;
           break;
         case 2:
           Content.link = WebsiteLink2;
           break;
         case 3:
          Content.link = WebsiteLink3;
          break;

         default:
         break;
     }

      lastViewController = Content;
      dispatch_async(dispatch_get_main_queue(), ^{
       [self.navigationController pushViewController:Content animated:YES];
      });
    }
 ];

}