2013-11-07 3 views
0

Из других вопросов мне кажется, что все, что мне нужно сделать, это добавить __block перед моей переменной, однако, похоже, он не работает для меня.Как назначить переменную внутри блока?

Внутри блока маркер правильно назначается при проверке с помощью NSLog(). Если я проверю его снова перед токеном возврата; он становится NULL.

- (NSString *)extractTokenFromURL:(NSURL *)tokenURL 
{ 
__block NSString *token = nil; 

NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] 
                 delegate:self 
               delegateQueue:nil]; 
[[session dataTaskWithURL:self.tokenURL 
     completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { 
    if (!error) { 
     NSHTTPURLResponse *httpResp = (NSHTTPURLResponse*) response; 
     if (httpResp.statusCode == 200) { 
      NSString *content = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; 
      NSRange divRange = [content rangeOfString:@"<div id='token' style='display:none;'>" options:NSCaseInsensitiveSearch]; 
      if (divRange.location != NSNotFound) { 
       NSRange endDivRange; 
       endDivRange.location = divRange.length + divRange.location; 
       endDivRange.length = [content length] - endDivRange.location; 
       endDivRange = [content rangeOfString:@"</div>" options:NSCaseInsensitiveSearch range:endDivRange]; 

       if (endDivRange.location != NSNotFound) { 
        divRange.location += divRange.length; 
        divRange.length = endDivRange.location - divRange.location; 

        dispatch_async(dispatch_get_main_queue(), ^{ 
         token = [content substringWithRange:divRange]; 
        }); 
       } 
      } 
     } 
    } 
}] resume]; 

return token; 
} 

ответ

2

Это потому, что задача выполняется асинхронно, поэтому этот метод будет возвращать до того token даже назначен.

Что вам нужно сделать, это передать блок завершения этому методу и вызвать его, как только у вас есть токен. Таким образом, вы не блокируете основной поток во время выполнения запроса.

Вот как вы можете это сделать:

- (void)extractTokenFromURL:(NSURL *)tokenURL completion:(void (^)(NSString *token, NSError* error))completion { 
    NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:nil]; 
    [[session dataTaskWithURL:self.tokenURL 
      completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { 
     if (!error) { 
      NSHTTPURLResponse *httpResp = (NSHTTPURLResponse*) response; 
      if (httpResp.statusCode == 200) { 
       NSString *token = // ...; 
       if (token) { // we have a valid token 
        if (completion) { 
         dispatch_async(dispatch_get_main_queue(), ^{ 
          completion(token, nil); 
         }); 
        } 
       } else if (completion) { 
        // create an error indicating why the token is not valid 
        NSError *error = // ...; 
        dispatch_async(dispatch_get_main_queue(), ^{ 
         completion(nil, error); 
        }); 
       } 
      } 
     } else if (completion) { 
      // send the http error. you could also wrap it on your own error domain and code 
      dispatch_async(dispatch_get_main_queue(), ^{ 
       completion(nil, error); 
      }); 
     } 
    }] resume]; 
} 

Вы также можете иметь два различных блока: один для успеха и еще один для отказа.

+0

Спасибо, можно ли получить пример кода? –

+0

Я обновил свой ответ. Взглянуть! –

+0

Спасибо, что сработало отлично. –

Смежные вопросы