2011-05-12 5 views
-1

, 내가 확인 로그인에 대해 하나의 웹 서비스를 호출 ... 응용 프로그램 Underprocess있을 때아이폰-uialertview-thred 아이폰에서

,, 내가 UIAlertview 스레드를 사용하여 UIActivityIndicatorView로보기 ,,

지금 내가 원하는 다음 내 애플 리케이션

를 호출하는 웹 서비스를 teminates하지만 난 취소 버튼을 사용할 때 다음 오류 OCccur는 하나는

를 도울 수 ,, 내가 그 프로세스를 취소하려면 과정을 의미합니다 ,, 버튼을 취소 할 수 있습니다

내 코드는 문제를 공격하는 방법을 몇 가지 주요 결함이 있습니다

-(NSMutableString*) getLoginMessage:(NSString*) UserName : (NSString *) Password 
{ 

    [NSThread detachNewThreadSelector:@selector(showAlertMethod) toTarget:self withObject:nil]; 

    NSArray *Keys =[[NSArray alloc] initWithObjects:@"LoginName",@"PassWord",nil]; 
    NSArray *KeyValue =[[NSArray alloc] initWithObjects:UserName,Password,nil]; 

    operationName=[[NSString alloc] init]; 
    operationName [email protected]"ClientLogin"; 
    NSString *StrService=[[NSUserDefaults standardUserDefaults] objectForKey:@"WebService"]; 
    NSURL *WebServiceUrl=[WebServiceHelper generateWebServiceHTTPGetURL:StrService : operationName : Keys :KeyValue]; 
    NSXMLParser *parser = [[NSXMLParser alloc] initWithContentsOfURL:WebServiceUrl]; 

    [parser setShouldReportNamespacePrefixes:NO]; 
    [parser setShouldResolveExternalEntities:NO]; 
    [parser setDelegate:self]; 
    [parser parse]; 

    [Keys release]; 
    [KeyValue release]; 
    [StrService release]; 
    [WebServiceUrl release]; 
    //[parser release]; 
    [NSThread detachNewThreadSelector:@selector(dismissAlertMethod) toTarget:self withObject:nil]; 

    return Result; 

} 
-(void)showAlertMethod 
{ 
    NSAutoreleasePool *pool1=[[NSAutoreleasePool alloc]init];   
    progressAlert = [[UIAlertView alloc] initWithTitle:@"Loging in...\nPlease wait...\n" message:@"" delegate:nil cancelButtonTitle:nil otherButtonTitles:nil]; 

    CGRect alertFrame = progressAlert.frame; 
    UIActivityIndicatorView* activityIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge]; 
    activityIndicator.frame = CGRectMake(135,alertFrame.size.height+75, alertFrame.size.width,30); 
    activityIndicator.hidden = NO; 
    activityIndicator.contentMode = UIViewContentModeCenter; 
    [activityIndicator startAnimating]; 
    [progressAlert addSubview:activityIndicator]; 
    [activityIndicator release]; 
    [progressAlert show]; 

    [pool1 release];  
} 
-(void)dismissAlertMethod 
{ 
    NSAutoreleasePool *pool2=[[NSAutoreleasePool alloc]init]; 
    [progressAlert dismissWithClickedButtonIndex:0 animated:YES]; 
    [pool2 release]; 
} 

답변

0

입니다. 첫째, 경고보기를 표시하거나 숨기려면 새 스레드를 분리하면 안됩니다. 모든 UIKit 클래스 이어야합니다. (문서화 된 예외는 거의 없습니다).

원하는 것은 로그인 요청을 보내기 위해 비동기로 설계된 API입니다. 나는 이것을 위해 Sync-Async 패턴을 사용할 것을 제안한다. 당신은 어떤 스레드가 좋아 없기 때문에

-(NSString*)loginMessageWithName:(NSString*)name 
         password:(NSString*)password 
          error:(NSError**)error; 
-(NSOperation*)loginMessageWithName:(NSString*)name 
         password:(NSString*)password 
         delegate:(id<LoginMessageDelegate>)delegate; 

는 첫 번째 방법은 동기와 같은 간단한 그것을 구현 : 두 개의 공용 메서드를 원하는 본질적으로 http://blog.jayway.com/2011/04/28/sync-asyn-pair-pattern-easy-concurrency-on-ios/

내가 생각 : 여기이 주제에 더 이상 블로그 게시물을 작성했습니다 어떤 일이 있어도 효과가 있습니다.

두 번째 방법은 NSOperation 개의 개체를 인스턴스화하고 일부 큐에 넣는 래퍼입니다. 작업을 반환하면 작업을 취소 할 수 있지만 결과는 대리자에 반환됩니다. 대리인은 아마 이런 식으로 뭔가를보고해야합니다

@protocol LogonMessageDelegate <NSObject> 
    -(void)didReceiveLoginMessage:(NSString*)message; 
    -(void)failedLoginMessageWithError:(NSError*)error; 
@end 

loginMessageWithName:password:delegate:의 구현은 매우 정직 : 대부분의 작업이 NSOperation 서브 클래스 'main 방식으로 수행됩니다

NSOperation* op = [[LoginMessageOperation alloc] initWithName:name 
                password:password 
                delegate:delegate]; 
[myOperationQueue addOperation:op]; 
return [op autorelease]; 

. 여기에서 동시 구현을 호출하고 취소를 확인한 다음 필요한 경우 대리인에게 다시 전화를 겁니다. 아마도 다음과 같을 것입니다 :

-(void)main { 
    NSError* error = nil; 
    NSString* message = [logonMessageManager logonWithName:name 
                password:password: 
                error:&error]; 
    if (![self isCancelled]) { 
     if (message) { 
      [delegate performSelectorOnMainThread:@selector(didReceiveLoginMessage:) 
             withObject:message 
            waitUntilDone:NO]; 
     } else { 
      [delegate performSelectorOnMainThread:@selector(didReceiveLoginMessage:) 
             withObject:error 
            waitUntilDone:NO]; 
     } 
    } 
} 

그런 다음 주 스레드에서 경고보기를 설정하고 처리하십시오. 대리자가 콜백을 받으면 사용자가 취소하거나 경고를 닫으면 [operation cancel]으로 전화하십시오.