2013-04-05 2 views
1

막 블록 작업을 시작했습니다 ... 매우 혼란 스럽습니다. 나는이 같은 블록을 사용하고 있습니다 : 연결이 완료블록을 사용하면 새 스레드가 자동으로 생성됩니까?

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 
NSDictionary *myDictionary = [[mySingleton arrayPeopleAroundMe] objectAtIndex:indexPath.row]; 

NSMutableString *myString = [[NSMutableString alloc] initWithString:@"http://www.domain.com/4DACTION/PP_profileDetail/"]; 
[myString appendString:[myDictionary objectForKey:@"userID"]]; 
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:[myString stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding]] 
              cachePolicy:NSURLRequestUseProtocolCachePolicy 
             timeoutInterval:60.0]; 
NSOperationQueue *queue = [[NSOperationQueue alloc] init]; 
[NSURLConnection 
sendAsynchronousRequest:urlRequest 
queue:queue 
completionHandler: ^(NSURLResponse *response, 
         NSData *data, 
         NSError *error) 
{ 
    [[mySingleton dictionaryUserDetail] removeAllObjects]; 
    [[mySingleton arrayUserDetail] removeAllObjects]; 

    if ([data length] > 0 && error == nil) // no error and received data back 
    { 
     NSError* error; 
     NSDictionary *myDic = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error]; 
     [mySingleton setDictionaryUserDetail:[myDic mutableCopy]]; 

     NSArray *myArray = [myDic objectForKey:@"searchResults"]; 
     [mySingleton setArrayUserDetail:[myArray mutableCopy]]; 

     [self userDetailComplete]; 
    } else if 
     ([data length] == 0 && error == nil) // no error and did not receive data back 
    { 
     [self serverError]; 
    } else if 
     (error != nil) // error 
    { 
     [self serverError]; 
    } 
}]; 
} 

되면,이 호출 할 때 : 팝업이 오류가 발생

-(void)userDetailComplete { 
ViewProfile *vpVC = [[ViewProfile alloc] init]; 
[vpVC setPassedInstructions:@"ViewDetail"]; 
[[self navigationController] pushViewController:vpVC animated:YES]; 
} 

: "는에서 웹 잠금을 얻기 위해 시도 이 스레드는 주 스레드 또는 웹 스레드가 아닌 다른 스레드에서 발생합니다. 이는 보조 스레드에서 UIKit을 호출 한 결과 일 수 있습니다. "

-(void)userDetailComplete { 
dispatch_async(dispatch_get_main_queue(), ^{ 
ViewProfile *vpVC = [[ViewProfile alloc] init]; 
[vpVC setPassedInstructions:@"ViewDetail"]; 
[[self navigationController] pushViewController:vpVC animated:YES]; 
}); 
} 

내 질문 : 내가 오류를 제거있어 유일한 방법은이에 userDetailComplete을 변경했습니다 새로운 스레드가 자동으로 블록을 사용할 때마다 시작인가? 블록을 사용할 때주의해야 할 다른 함정이 있습니까?

답변

7

블록은 스레드를 생성하지 않습니다. 그들은 폐쇄입니다. 그들은 미래의 어떤 시점에서 실행될 수있는 실행 가능한 코드를 포함합니다.

NSOperationQueue *queue = [[NSOperationQueue alloc] init]; 
[NSURLConnection 
    sendAsynchronousRequest:urlRequest 
    queue:queue 
    ... 

당신은 새로운 큐를 만든 다음 다시 해당 큐에 전화 할 NSURLConnection를 질문 : 그것은 당신이 그것을 물어 무엇 때문에

이 백그라운드 스레드에서 실행됩니다. 메인 스레드에서 다시 호출되기를 원하면 [NSOperationQueue mainQueue]을 전달하십시오. 그것은 보통 당신이 원하는 것입니다.

+0

그리고 나는 백그라운드 VC에서 푸시 (push)와 같은 UI 요소를 수행 할 수 없다고 가정합니다. – sangony

+1

맞습니다. UIKit은 스레드로부터 안전하지 않습니다. 이것은 블록에서 UI 작업을 할 수 없다는 것을 의미하지는 않습니다. 블록이 주 스레드에서 실행되어야한다는 것입니다. –

+0

알았어요. 마지막 후속 질문 ... 위의 코드에서와 같이 블록을 사용하거나 NSURL 및 그 대리자와 연결하는 것이 더 바람직합니까? 블록 주위에서 머리를 감싸려고 노력하고 있기 때문에 질문하고 있습니다. 실제로 블록인지 궁금해합니다. 이 시점에서 노력할 가치가 있습니다. – sangony

관련 문제