penguin-penpen penguin-penpen - 2 years ago 103
iOS Question

ios - Program with block executed out of order?

I'm trying to get an array of urls from my backend.

I use

AFNetworking
and I have a
HTTPUtil
class implemented as
singleton
to handle my requests.

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);
}];
}


In my view controller, I call the method to fetch the array.

_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);
}];


In the console, I got

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;
}


I thought
imgArr
should be assigned in the
success
block and it shouldn't be
nil
when I assign it to
_vCycleScrollView.imageURLStringsGroup
.


However, I can tell from the output in the console that the
HTTP
request is sent after
NSLog(@"adding...");
and that leads to the fact that
imgArr
is still
nil
when
_vCycleScrollView.imageURLStringsGroup = imgarr;
is executed.

Why is that?

Answer Source

Yes below code is in block so this will continue in background

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

solution - You should add _vCycleScrollView.imageURLStringsGroup = imgarr; inside of success block because you d0 not know when it will completed Or there is another way you should not call in block or should not create block.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download