2012-04-19 72 views
1

我正在使用AFNetworking客戶端對象,它爲XML文檔提出異步請求並對其進行分析。NSNotificationCenter - 等待通知發佈而不阻塞主線程的方式?

還使用NSNotificationCenter在文檔解析完成後發佈通知。

有沒有一種方法來等待爲通知發佈而不阻塞主線程?

E.g代碼:

-(void)saveConfiguration:(id)sender { 

    TLHTTPClient *RESTClient = [TLHTTPClient sharedClient]; 

    // Performs the asynchronous fetching....this works. 
    [RESTClient fetchActiveUser:[usernameTextField stringValue] withPassword:[passwordTextField stringValue]]; 

    /* 
    * What do I need here ? while (xxx) ? 
    */ 

    NSLog(@"Fetch Complete."); 

} 

基本上我想知道什麼樣的代碼,我需要在上述指定區域,以確保等待直到函數的獲取已經完成?

因爲它現在我會看到「Fetch Complete」。在提取完成之前,在調試控制檯中調用

我嘗試添加一個BOOL標誌提供給TLHTTPClient類:

BOOL fetchingFlag; 

然後嘗試:

while([RESTClient fetchingFlag]) { NSLog(@"fetching...); } 

當這個類接收它設置RESTClient.fetchingFlag = FALSE的通知;這應該在技術上殺死while循環嗎?除了我的while循環無限運行?!

+0

你可以在另一個線程中等待嗎? – MechEthan 2012-04-19 15:16:37

+0

你可以在單獨的線程中進行解析 – Kamal 2012-04-19 15:16:50

+7

如果你註冊了一個通知,你已經在等待了,而沒有阻塞主線程,對吧? – 2012-04-19 15:41:12

回答

2

基本上我想知道在上面指定的區域需要什麼類型的代碼來確保函數等待直到獲取完成?

您需要無代碼。開始提取後,請勿在方法中添加任何內容,並且不會發生任何事情。您的程序將「等待」(它實際上會處理其他輸入),直到收到通知。

在通知處理程序方法中,放置完成提取時需要執行的所有操作。這是通知和其他回調方案(的一個) - 你的對象只有在得到通知後才能採取行動。

有沒有辦法等待通知被張貼不阻塞主線程?

這正是它的工作原理。

+0

之後,你說,然後重新思考我想要完成的事情,並重新檢查我的代碼,你確實是對的!謝謝! – 2012-04-19 18:56:10

+0

很高興我能幫到你。 – 2012-04-19 18:56:27

0

如果在完成任務時不需要通知多個對象,則可以在-fetchActiveUser:withPassword:方法中添加完成處理程序(objc塊)(因此它將變成類似-fetchActiveUser:withPassword:completionHandler:的類似程序,並添加要在其中執行的代碼。完成處理

一個例子,讓我們說你-fetchActiveUser:withPassword:completionHandler:方法如下所示:

- (void)fetchActiveUser:(NSString *)user 
      withPassword:(NSString *)pass 
     completionHandler:(void (^)(TLUser *user, NSError *error))handler 
{ 
    NSURL *URL     = [NSURL URLWithString:@"http://www.website.com/page.html"]; 
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:URL];  
    NSOperationQueue *queue  = [NSOperationQueue currentQueue]; 
    [NSURLConnection sendAsynchronousRequest:request 
             queue:queue 
          completionHandler:^ (NSURLResponse *response, NSData *data, NSError *error) 
    { 
     if (!handler) 
     { 
      return 
     }; 

     if (data) 
     { 
      TLUser *user = [TLUser userWithData:data]; 

      if (user) 
      { 
       handler(user, nil); 
      } 
      else 
      { 
       NSError *error = // 'failed to create user' error ... 
       handler(nil, error); 
      } 
     } 
     else 
     { 
      handler(nil, error); 
     } 
    }]; 
} 

每當任務完成後完成處理程序將調用它要麼返回TLUser對象或錯誤。如果出現問題(連接不良,數據錯誤)格式在解析時發生了變化等)。

你就可以這樣調用方法:

- (void)saveConfiguration:(id)sender 
{ 
    TLHTTPClient *RESTClient = [TLHTTPClient sharedClient]; 


    // Performs the asynchronous fetching 

    [RESTClient fetchActiveUser:[usernameTextField stringValue] 
        withPassword:[passwordTextField stringValue] 
       completionHandler:^ (TLUser *user, NSError *error) 
    { 
     if (user) 
     { 
      NSLog(@"%@", user); 
     } 
     else 
     { 
      NSLog(@"%@", error);  
     } 
    }]; 
} 

當然,在這個例子中,我在AFNetworking代替NSURLConnection的異步方法的構建中,但你應該能夠得到大致的想法。