[英]Returning a BOOL method inside a block?
我有這個布爾方法,它為輸入的字符串返回是或否。 我能夠成功返回YES
或NO
,但似乎無法建立網絡連接並根據服務器的響應返回YES
或NO
。 我嘗試使用__block
,但我不認為那樣會等待Web請求完成,是否有一種方法可以在成功塊中返回YES
或NO
,而不會給我錯誤:
不兼容的塊指針類型將'BOOL(^)(NSURLSessionTask * __ strong,NSError __strong')發送到類型為'void(^)(NSURLSessionTask ...)的參數
-(BOOL)customResponseForString:(NSString *)text {
__block BOOL response_available;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
manager.responseSerializer = [AFHTTPResponseSerializer serializer];
[manager.responseSerializer setAcceptableContentTypes:[NSSet setWithObject:@"text/plain"]];
[manager GET:[NSString stringWithFormat:@"http://example.com/response.php?input=%@", text] parameters:nil success:^(NSURLSessionDataTask *task, id responseObject) {
NSDictionary *response = [NSJSONSerialization JSONObjectWithData:responseObject options:NSUTF8StringEncoding error:nil];
response_available = (BOOL)response[@"response_available"];
if (response_available) {
[session sendTextSnippet:response[@"response"] temporary:NO scrollToTop:NO dialogPhase:@"Summary"];
} else {
response_available = NO;
}
[session sendTextSnippet:[[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding] temporary:NO scrollToTop:NO dialogPhase:@"Summary"];
[session sendRequestCompleted];
} failure:^(NSURLSessionDataTask *task, NSError *error) {
//return NO;
}];
});
return response_available;
}
您的塊定義語法可能是錯誤的,因為您可以肯定地將BOOL和其他參數一起返回。
- (void)fetchCurrentUserWithCompletion:(void (^)(BOOL success, User *user))completion;
該方法將這樣調用:
[self.userProfileController fetchCurrentUserWithCompletion:^(BOOL success, User *user) {
if (success) {
NSLog(@"Current User Name: %@", user.fullName);
}
}];
如果使用AFNetworking,請檢查處理AFHTTPRequestOperation
對象:
[requestOperation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
User *user = [self userFromResponseObject:responseObject];
if (completion) completion(YES, user);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
if (completion) completion(NO, user);
}];
因為您隱式地將response_available
初始化為NO
,然后使用異步GCD調用,所以您編寫的方法將始終立即返回NO
而無需等待請求完成。 注意:切換到dispatch_sync
也無濟於事,因為AFNetworking會以任何一種方式異步將GET請求排隊。
最佳方法
向customResponseForString:
添加一個完成塊參數。 然后,只需在AFHTTPRequestOperation
的成功或失敗塊中執行您的完成塊AFHTTPRequestOperation
。
可行的方法 (請謹慎使用!)
可以使customResponseForString:
等待對網絡請求的響應,但是如果從主線程調用它,則將遇到重大問題。
首先,您創建一個調度組,並告訴它您正在開始一些長期運行的工作:
dispatch_group_t networkGroup = dispatch_group_create();
dispatch_group_enter(networkGroup);
然后,您需要發出網絡請求,並在網絡請求完成時使用dispatch_group_leave()
告知工作組工作已完成:
[manager GET:[NSString stringWithFormat:@"http://example.com/response.php?input=%@", text] parameters:nil success:^(NSURLSessionDataTask *task, id responseObject) {
NSDictionary *response = [NSJSONSerialization JSONObjectWithData:responseObject options:NSUTF8StringEncoding error:nil];
response_available = (BOOL)response[@"response_available"];
if (response_available) {
[session sendTextSnippet:response[@"response"] temporary:NO scrollToTop:NO dialogPhase:@"Summary"];
} else {
response_available = NO;
}
[session sendTextSnippet:[[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding] temporary:NO scrollToTop:NO dialogPhase:@"Summary"];
[session sendRequestCompleted];
dispatch_group_leave(networkGroup);
} failure:^(NSURLSessionDataTask *task, NSError *error) {
response_available = NO;
dispatch_group_leave(networkGroup);
}];
在您的原始方法返回之前,告訴它等待整個組完成處理:
dispatch_group_wait(networkGroup, DISPATCH_TIME_FOREVER);
return response_available;
您可以根據需要調整此時間間隔,也可以將其保留在DISPATCH_TIME_FOREVER
以使網絡請求自行超時。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.