2016-04-02 75 views
1

我有這樣的方法試圖瞭解異步調用

- (NSString*) createUserWithName:(NSString*)TheName 
{ 
    NSURL *URL =someUrlthatIncludesTheName 
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url]]; 
    [request setHTTPMethod:@"GET"]; 
    NSURLSession *session = [NSURLSession sharedSession]; 
    NSURL *URL = [NSURL URLWithString:url]; 
    NSURLSessionTask *task = [session dataTaskWithURL:URL completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { 
     if (response) { 
      NSError* error = nil; 
      NSArray *output = [NSJSONSerialization JSONObjectWithData:data 
                   options:NSJSONReadingMutableContainers 
                   error:&error]; 
      myID = [[output objectAtIndex:0] objectForKey:@"UserID"]; 
     } 
    }]; 
    [task resume]; 
    return myID; 
} 

而另一種方法

-(void)doSomethingWith: (NSString*) anID 

某處在我的代碼,我隨後調用這些方法,像這樣:

[self createUserWithName:@"John"]; 
[self doSomethingWith:myID]; 

但是,由於NSURLSession in createUserWithName:是異步的,doSomethingWith:myID =(null)一起被觸發。

解決此問題的最佳方法是什麼,而不必回退到廢棄的同步NSURLConnection?提前

+0

這是因爲''而所述方法[自doSomethingWith:本身份識別碼] createUserWithName'尚未完成調用它執行'。你可以調用'[self doSomethingWith:myID];'進入'createUserWithName'方法或者使用CompletionBlock – vroldan

回答

4

由於工作流程應該是

- (void)createUserWithName:(NSString*)TheName 
{ 
    NSURL *URL =someUrlthatIncludesTheName 
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url]]; 
    [request setHTTPMethod:@"GET"]; 
    NSURLSession *session = [NSURLSession sharedSession]; 
    NSURL *URL = [NSURL URLWithString:url]; 
    NSURLSessionTask *task = [session dataTaskWithURL:URL completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { 
     if (response) { 
      NSError* error = nil; 
      NSArray *output = [NSJSONSerialization JSONObjectWithData:data 
                   options:NSJSONReadingMutableContainers 
                   error:&error]; 
      myID = [[output objectAtIndex:0] objectForKey:@"UserID"]; 
      [self doSomethingWith:myID]; 
     } 
    }]; 
    [task resume]; 
} 

和呼叫僅

[self createUserWithName:@"John"]; 

的方法doSomethingWith:在完成塊的異步執行。

替代地使用定製完成塊

- (void)createUserWithName:(NSString *)theName completion:^(NSString *identifier)completion 
{ 
    NSURL *URL =someUrlthatIncludesTheName 
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url]]; 
    [request setHTTPMethod:@"GET"]; 
    NSURLSession *session = [NSURLSession sharedSession]; 
    NSURL *URL = [NSURL URLWithString:url]; 
    NSURLSessionTask *task = [session dataTaskWithURL:URL completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { 
     if (response) { 
      NSError* error = nil; 
      NSArray *output = [NSJSONSerialization JSONObjectWithData:data 
                  options:NSJSONReadingMutableContainers 
                  error:&error]; 
      myID = [[output objectAtIndex:0] objectForKey:@"UserID"]; 
      completion(myID); 
     } 
    }]; 
    [task resume]; 
} 

並用

[self createUserWithName:@"John" completion:^(NSString *identifier) { 
    [self doSomethingWith:identifier]; 
}]; 
+0

我想這個技巧。 爲了這個問題,我簡化了我的代碼。事實上,「doSomethingWith:」帶來了其他一些爭論。所以,我應該將所有這些參數都傳遞給「createUserWithName」,這使得代碼不可讀。 – Sjakelien

+1

另一種方法是在'createUserWithName:'方法中添加一個完成塊。然後您可以捕獲塊中的其他參數。 – vadian