ios - 程序块乱序执行?
ios - Program with block executed out of order?
我正在尝试从我的后端获取一组 url。
我使用 AFNetworking
并且我有一个 HTTPUtil
class 作为 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
块中赋值,当我赋值给_vCycleScrollView.imageURLStringsGroup
时不应该是nil
。
但是,我可以从控制台的输出中看出 HTTP
请求是在 NSLog(@"adding...");
之后发送的,这导致 imgArr
仍然是 nil
当执行 _vCycleScrollView.imageURLStringsGroup = imgarr;
时。
这是为什么?
这就是整个想法:块是乱序执行的。诀窍是您不必等待 块完成。相反,块完成,然后执行所需的操作。您 viewcontroller 中的代码将无法运行,无法运行,我们也不希望它运行。相反,回调块将图像存放在某处,然后告诉 tableview 重新加载该行。
是的,下面的代码在块中,所以这将在后台继续
[[HTTPUtil sharedInstance] getImageArrayFromURL:url success:^(NSArray* array){
imgarr = [NSArray arrayWithArray:array];
}failure:^(NSError* error){
NSLog(@"%@", error);
}];
解决方案 - 你应该在成功块中添加 _vCycleScrollView.imageURLStringsGroup = imgarr; 因为你不知道它什么时候会完成 或者还有另一种你不应该调用的方法在块中或不应创建块。
试试下面的方法:
__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 为 nil 的原因。
我正在尝试从我的后端获取一组 url。
我使用 AFNetworking
并且我有一个 HTTPUtil
class 作为 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
块中赋值,当我赋值给_vCycleScrollView.imageURLStringsGroup
时不应该是nil
。
但是,我可以从控制台的输出中看出 HTTP
请求是在 NSLog(@"adding...");
之后发送的,这导致 imgArr
仍然是 nil
当执行 _vCycleScrollView.imageURLStringsGroup = imgarr;
时。
这是为什么?
这就是整个想法:块是乱序执行的。诀窍是您不必等待 块完成。相反,块完成,然后执行所需的操作。您 viewcontroller 中的代码将无法运行,无法运行,我们也不希望它运行。相反,回调块将图像存放在某处,然后告诉 tableview 重新加载该行。
是的,下面的代码在块中,所以这将在后台继续
[[HTTPUtil sharedInstance] getImageArrayFromURL:url success:^(NSArray* array){
imgarr = [NSArray arrayWithArray:array];
}failure:^(NSError* error){
NSLog(@"%@", error);
}];
解决方案 - 你应该在成功块中添加 _vCycleScrollView.imageURLStringsGroup = imgarr; 因为你不知道它什么时候会完成 或者还有另一种你不应该调用的方法在块中或不应创建块。
试试下面的方法:
__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 为 nil 的原因。