ios - 程序块无序执行?

时间:2016-05-20 06:50:29

标签: ios objective-c afnetworking

我正试图从我的后端获取一系列网址。

我使用AFNetworking我有一个HTTPUtil类实现为singleton来处理我的请求。

HTTPUtil.m

#import "HTTPUtil.h"

@implementation HTTPUtil

+(instancetype)sharedInstance{
    NSLog(@"sharedInstance");    //to check the order
    static HTTPUtil* manager;
    static dispatch_once_t once;
    dispatch_once(&once, ^{
        manager = [[HTTPUtil alloc] init];
    });
    manager.responseSerializer = [AFJSONResponseSerializer serializer];
    manager.requestSerializer = [AFJSONRequestSerializer serializer];
    return manager;
}

-(void)getImageArrayFromURL:(NSString *)url success:(void(^)(NSArray* array))success failure:(void(^)(NSError* error))failure{
    NSLog(@"getting...");    //to check the order
    [self GET:url parameters:nil progress:nil success:^(NSURLSessionDataTask* task, id response){
        NSLog(@"Response: %@", response);
        NSString* imgStr = [[response objectForKey:kResponseDataKey] objectForKey:@"img"];

        //convert nsstring to nsarray
        NSArray* array = [StringUtil arrayFromString:imgStr];

        //construct urls
        NSMutableArray* ret = [[NSMutableArray alloc] init];
        NSMutableString* url;
        for (NSString* rawStr in array) {
            url = [NSMutableString stringWithString:kUrlBase];
            [url appendString:[rawStr stringByReplacingOccurrencesOfString:@"/" withString:@"+"]];
            [ret addObject:url];
        }
        success(ret);
    }failure:^(NSURLSessionDataTask* task, NSError* error){
        NSLog(@"Error: %@", error);
        failure(error);
    }];
}

在我的视图控制器中,我调用该方法来获取数组。

    _vCycleScrollView = [SDCycleScrollView cycleScrollViewWithFrame:CGRectMake(0, 0, 0, 0) delegate:self placeholderImage:[UIImage imageNamed:@"checked"]];
    NSMutableString* url = [NSMutableString stringWithString:kUrlBase];
    [url appendString:@"activityImgArray"];
//
     __block NSArray* imgarr;
    [[HTTPUtil sharedInstance] getImageArrayFromURL:url success:^(NSArray* array){
        imgarr = [NSArray arrayWithArray:array];
    }failure:^(NSError* error){
        NSLog(@"%@", error);
    }];
    NSLog(@"adding...");
    _vCycleScrollView.imageURLStringsGroup = imgarr;

[self.view addSubview:_vCycleScrollView];
[_vCycleScrollView mas_makeConstraints:^(MASConstraintMaker* make){
    make.top.equalTo(self.view);
    make.left.equalTo(self.view);
    make.right.equalTo(self.view);
    make.height.mas_equalTo(180);
    make.width.equalTo(self.view.mas_width);
}];

在控制台中,我得到了

2016-05-20 14:41:19.411 SCUxCHG[10470:4909076] sharedInstance
2016-05-20 14:41:19.415 SCUxCHG[10470:4909076] getting...
2016-05-20 14:41:19.417 SCUxCHG[10470:4909076] adding...
2016-05-20 14:41:19.591 SCUxCHG[10470:4909076] 
Response: {
    data =     {
        img = "[activity/test1, acti/1]";
    };
    message = success;
    result = 0;
}

我认为imgArr 应该在success块中分配,当我将其分配给nil时,它不应该是_vCycleScrollView.imageURLStringsGroup

但是,我可以从控制台的输出中判断HTTP请求是在NSLog(@"adding...");之后发送的,这导致imgArr仍然是nil时的事实_vCycleScrollView.imageURLStringsGroup = imgarr;已执行。

为什么?

3 个答案:

答案 0 :(得分:2)

是的,下面的代码是阻止的,所以这将在后台继续

[[HTTPUtil sharedInstance] getImageArrayFromURL:url success:^(NSArray* array){
    imgarr = [NSArray arrayWithArray:array];
}failure:^(NSError* error){
    NSLog(@"%@", error);
}];

解决方案 - 您应该在成功块中添加 _vCycleScrollView.imageURLStringsGroup = imgarr; ,因为您不知道它何时会完成或者有另一种方法您不应该在块中调用或者不应该创建块

答案 1 :(得分:1)

试试下面的话:

 __block NSArray* imgarr;
[[HTTPUtil sharedInstance] getImageArrayFromURL:url success:^(NSArray* array){
    imgarr = [NSArray arrayWithArray:array];
    NSLog(@"adding...");
    _vCycleScrollView.imageURLStringsGroup = imgarr;
}failure:^(NSError* error){
    NSLog(@"%@", error);
}];

获取数据后执行完成块。 在您的情况下,代码在设置完成块之后继续执行但尚未获取数据,这就是为什么imgarr为零。

答案 2 :(得分:0)

这就是整个想法:那些块是乱序执行的。诀窍是你不等待一个块完成。相反,块完成然后它完成所需的操作。 viewcontroller中的代码不起作用,无法工作,我们不希望它工作。相反,回调块将图像存放在某处,然后告诉tableview重新加载该行。