<分区>
<分区>
{ __weak idweakSelf = self;
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);
}];
}
-(void)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*) 消息永远不会被调用。
有什么想法吗?
最佳答案
如果 ClientManager
调用是异步的,则 populateTextViews
方法将在异步调用返回之前完成,这就是您无法使用其完成 block 中设置的值的原因。
要么放...
NSMutableAttributedString *postText = [[NSMutableAttributedString alloc] initWithString:messageText];
...在完成 block 内,或者在获得 messageText 后调用完成 block 内的方法。这样做时,您也不必声明 __block 变量。
如果有 UI 更新,请确保更新发生在主线程上。
编辑
这是基本想法,但我猜您正在更新多个 TextView ,因此您可能需要更改周围的签名。如果您了解基本想法 - 调用异步方法不会中断代码流程(基本上它说“当您有机会时执行此操作,可能在另一个线程上”)。这就是你有一个完成 block 的原因——它是代码中你知道你调用的异步方法已经完成的地方。
如果 block 内的内容根本没有被调用,请确保 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;
}
关于ios - 如何从完成 block 中获取变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18423445/
相关文章:
ios - 使用程序化自动布局时容器 View 的框架设置为 CGRectZero
multithreading - 当 main 退出时,控制台输出到哪里?
.net - 在 .NET 中通过 Process.Start 生成的进程会挂起线程
python - 传递给 C API 的参数对于 Python 中的子线程没有意义
ios - 从我的 iPhone 或 Blackberry 访问本地托管的 Web 服务
ios - UIImagePickerController - 将图片裁剪成正方形(纵向)
ios - 如果来自 URL 的 XML 文件未加密,我如何在 iOS 中发现?