我一直在尝试从教程中试验一些代码,但由于没有理解GCD而没有取得多大成功。
我有一个名为API.m的类,这里是关于GCD的代码:
+ (API *) sharedInstance
{
static API *sharedInstance = nil;
static dispatch_once_t oncePredicate;
dispatch_once(&oncePredicate, ^{
sharedInstance = [[self alloc] initWithBaseURL:[NSURL URLWithString:APIHost]];
});
return sharedInstance;
}
-(void)commandWithParams:(NSMutableDictionary*)params
onCompletion:(JSONResponseBlock)completionBlock
{
NSMutableURLRequest *apiRequest = [self multipartFormRequestWithMethod:@"POST"
path:APIPath
parameters:params
constructingBodyWithBlock: ^(id <AFMultipartFormData>formData) {
//TODO: attach file if needed
}];
AFJSONRequestOperation* operation = [[AFJSONRequestOperation alloc] initWithRequest: apiRequest];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
//success!
completionBlock(responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
//failure :(
completionBlock([NSDictionary dictionaryWithObject:[error localizedDescription] forKey:@"error"]);
}];
[operation start];
}
我通过实现一个按钮并让NSArray将其内容打印到输出窗口来进行简单的测试:
- (IBAction)test:(id)sender {
NSMutableDictionary* params =[NSMutableDictionary dictionaryWithObjectsAndKeys:
@"pending", @"command",
[[[API sharedInstance] user] objectForKey:@"UserID"] , @"userID",
nil];
[[API sharedInstance] commandWithParams:params
onCompletion:^(NSDictionary *json) {
//result returned
if ([json objectForKey:@"error"]==nil) {
// Simple example
[self.users addObject:@"1"];
} else {
//error
[UIAlertView title:@"Error" withMessage:[json objectForKey:@"error"]];
}
}];
NSLog(@"%@", self.users);
}
现在,当我第一次点击按钮时,一个空的NSArray被打印到输出窗口,但是当我再次按下它时会打印出“1”。很明显,程序在完成块有时间完全执行之前到达NSLog。有人可以帮我修改代码,以便我可以选择在完成块完成后执行NSLog吗?
答案 0 :(得分:1)
不确定您要完成的任务,但如果目标是在完成块之后执行NSLog,则可以在
之后移动NSLog语句[self.users addObject:@"1"];
如果在将数据添加到数组后要执行某些代码,则可以使用
[self methodName]; in the completion block and it will get called there.
完成块,是执行您想要运行的代码后运行的代码。您希望运行的代码将异步发生在另一个线程上。运行该代码后,将执行完成块代码。