2013-08-24 22 views
0
  • (無效)fetchLastMessageInChannel

{ __weak ID weakSelf =自我;如何從完成塊中獲取變量?

for (ANKChannel *channel in self.channelArray) 
    { 
      NSLog(@"channels %@",channel); 

      NSLog(@"channel last message %@",channel.latestMessageID); 

     [[ClientManager currentClient] fetchMessageWithID:channel.latestMessageID inChannel:channel 
               completion:^(id responseObject, ANKAPIResponseMeta *meta, NSError *error) 
     { 
      NSLog(@"message object %@",responseObject); 
      ANKMessage *message = responseObject; 

      dispatch_async(dispatch_get_main_queue(), ^{ 
       [weakSelf populateTextViews:message.text]; 
      }); 

      NSLog(@"message text %@",message.text); 

     }]; 

    } 

}

- (空)populateTextViews:(的NSString *)消息 {

NSMutableArray *textViews = [@[] mutableCopy]; 

NSMutableAttributedString *postText = [[NSMutableAttributedString alloc] initWithString:message]; 
[postText addAttributes:@{ 
          NSFontAttributeName : [UIFont preferredFontForTextStyle:UIFontTextStyleBody], 
          NSForegroundColorAttributeName : [UIColor darkTextColor] 
          } 
        range:NSMakeRange(0, postText.length)]; 

UITextView *postTextView = [[UITextView alloc] initWithFrame:CGRectMake(80, 30, kPostLabelMaxWidth, 44)]; 
postTextView.attributedText = postText; 
postTextView.dataDetectorTypes = UIDataDetectorTypeAll; 
postTextView.backgroundColor = [UIColor whiteColor]; 
postTextView.editable = NO; 
postTextView.scrollEnabled = NO; 
postTextView.clipsToBounds = NO; // So it doesn't clip the text selector 

CGRect textViewBounds = postTextView.bounds; 
textViewBounds.origin = CGPointMake(80, 30); 
textViewBounds.size.width = MAX(textViewBounds.size.width, kPostLabelMaxWidth); 
textViewBounds.size.height = postTextView.contentSize.height; 


postTextView.bounds = textViewBounds; 

[postTextView sizeToFit]; // Reload the content size 

[textViews addObject:postTextView]; 



self.channelTextViewArray = [textViews copy]; 

}

這是我目前的處境至於我的方法去我收到的幫助。 self.channelTextViewArray返回nil並導致崩潰,因爲populateTextViews(NSString *)消息永遠不會被調用。

任何想法?

+0

,因爲有一個「小」的問題與你的邏輯:在信息,你想要得到_outside_塊的範圍將可用_after_了'NSLog'運行_outside_的塊。你只需要同步這些線程來達到你想要的效果,但是你不應該阻塞主線程直到塊完成。可能,你需要爲它使用不同的代碼模式,而不是你已經使用的代碼模式。 – holex

+0

我是一個自學成才的程序員,只有8個月的經驗,所以我不知道任何事情,但我很感激幫助。你所談論的代碼模式的任何建議? –

+0

通過'GitHub'或'Bitbucket'向我發送源代碼鏈接,我會看看它。 – holex

回答

1

如果ClientManager調用是異步的,那麼populateTextViews方法將在異步調用返回之前完成,這就是爲什麼您不能使用其完成塊中設置的值。

要麼把...

NSMutableAttributedString *postText = [[NSMutableAttributedString alloc] initWithString:messageText]; 

...完成塊內,或調出該塊完成,一旦你有MessageText中內的方法。這樣做你不必聲明__block變量。

如果將有UI更新,請確保發生在主線程上。

編輯

這基本的想法,但我猜你要更新超過一個文本視圖,所以你可能需要改變周圍的簽名。如果你有了基本的想法 - 調用一個異步方法不會中斷你的代碼流(基本上它說「當你有機會時,可能在另一個線程上這樣做」)。這就是你有一個完成塊的原因 - 它是你的代碼中的一個地方,你知道你調用的異步方法已經完成。

如果塊內沒有被調用,請確保self.channelArray具有值,並查看fetchMessageWithID在出現問題時會做什麼。

- (void)populateTextViews 
{ 
    __weak id weakSelf = self; 
    for (ANKChannel *channel in self.channelArray) 
    {  
     [[ClientManager currentClient] fetchMessageWithID:channel.latestMessageID inChannel:channel 
               completion:^(id responseObject, ANKAPIResponseMeta *meta, NSError *error) 
     { 
      NSLog(@"message object %@",responseObject); 
      ANKMessage *message = responseObject; 
      dispatch_async(dispatch_get_main_queue(), ^{ 
       [weakSelf updateTextView:message.text]; 
      });   
     }]; 
    } 
} 

- (void)updateTextView:(NSString *)message 
{ 
    // Make an attributed string from the post text content 
    NSMutableAttributedString *postText = [[NSMutableAttributedString alloc] initWithString:messageText]; 
    self.textView.attributedText = postText; 
} 
當然它是不工作的
+0

好吧,我會試試這個。 –

+0

我在塊內部調用另一個方法,但是當我放置斷點時,塊內的內容不會再被調用。我在塊中做了這樣的事情...... [self populateTextViewWithString:messageText]; –

+0

編輯答案,看看它是否有幫助。一會兒。 –