私はチュートリアルからいくつかのコードを試してみましたが、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 を実行するオプションがあるように、誰かがコードを変更するのを手伝ってくれませんか?