簡體   English   中英

返回塊內的BOOL方法?

[英]Returning a BOOL method inside a block?

我有這個布爾方法,它為輸入的字符串返回是或否。 我能夠成功返回YESNO ,但似乎無法建立網絡連接並根據服務器的響應返回YESNO 我嘗試使用__block ,但我不認為那樣會等待Web請求完成,是否有一種方法可以在成功塊中返回YESNO ,而不會給我錯誤:

不兼容的塊指針類型將'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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM