OBJ-C:__块变量不保留数据 [英] Obj-C: __block variable not retaining data

查看:0
本文介绍了OBJ-C:__块变量不保留数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想我这里可能有一个异步问题,这很刺痛,因为我以为我已经解决了它。无论如何,我正在进行一系列Web服务调用,如下所示:

//get the client data
__block NSArray* arrClientPAs;
[dataManager getJSONData:strWebService withBlock:^(id results, NSError* error) {            
    if (error) {
        UIAlertView* alert = [[UIAlertView alloc] initWithTitle:@"Getting Client Data Error!" message:error.description delegate:nil cancelButtonTitle:NSLocalizedString(@"Okay", nil) otherButtonTitles:nil, nil];
        [alert show];
    } else {
        arrClientPAs = results;
    }
 }];

和getJSONData是这样的:

- (void) getJSONData : (NSString*) strQuery withBlock:(void (^)(id, NSError *))completion {
    NSDictionary* dictNetworkStatus = [networkManager checkNetworkConnectivity];
    NetworkStatus networkStatus = [[dictNetworkStatus objectForKey:@"Status"] intValue];

    if (networkStatus != NotReachable) {
        //set up the url for webservice
        NSURL* url = [NSURL URLWithString:strQuery];
        NSMutableURLRequest* urlRequest = [NSMutableURLRequest requestWithURL:url];

        //set up the url connection
        __block id results;
        [NSURLConnection sendAsynchronousRequest:urlRequest queue:[NSOperationQueue mainQueue] completionHandler:
         ^(NSURLResponse* response, NSData* jsonData, NSError* error) {
             if (error) {
                 completion(nil, error);
                 return;
             }

            results = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers | NSJSONReadingMutableLeaves | NSJSONReadingAllowFragments error:&error]; 
            completion(results, nil);
         }];            
    } else {
        //not connected to a network - data is going to have to come from coredata
    }
}
在第一个块中,如果我登录arrClientData,我可以看到我期望的数据,但是当我在它之后登录arrClientData时,它是空的。我一直在关注这个帖子-How to return a BOOL with asynchronous request in a method? (Objective-C)和其他几个帖子。

显然,我正在尝试在进行异步调用后获取数据。任何帮助都将不胜感激。

推荐答案

我认为,问题在于"异步"是什么意思。图表如下:

Step One
__block result;
Step Two - do something asynchonous, including e.g. setting result
Step Three

这里的事情发生的顺序是什么?第三步发生在第二步完成之前。这就是异步的含义:它的意思是,"继续这个代码,不要等到异步的东西完成。"因此,在第三步发生时,result变量尚未设置为任何值。

因此,您的__block result完全是在误导您自己。__block或无__block,您无法在之后找出result是什么,因为没有"事后"。您的代码甚至在__block result设置之前就已完成。这就是为什么异步代码使用回调(例如。您的completion块),在之后运行,因为它是异步代码的顺序部分(附加到)。您可以通过回调将结果向下传递,但不能从块内向上有效地设置它,并期望稍后检索它。

因此,您的总体结构如下所示:

__block NSArray* arrClientPAs; // it's nil
[call getJSONdata] = step one
     [call sendAsynchronousRequest]
          do the block _asynchronously_ = step two, tries to set arrClientPAs somehow
step three! This happens _before_ step two, ...
... and this entire method ends and is torn down ...
... and arrClientPAs is still nil! 🌻
我重复一遍:您不能将任何信息传递出异步块。你只能往下走。您需要使用异步块来调用某个独立持久对象的某个方法,以便将结果传递给它,并告诉它使用该结果(在主线程上小心操作,否则将造成严重破坏)。您不能将任何自动变量用于此目的,例如声明的NSArray变量arrClientPAs;不再有自动作用域,方法已结束,自动变量已消失,不再有要运行的代码。

这篇关于OBJ-C:__块变量不保留数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆