Ios 如何从完成块中获取变量? (void)fetchLastMessageInChannel
{ __弱id weakSelf=自我Ios 如何从完成块中获取变量? (void)fetchLastMessageInChannel,ios,objective-c,multithreading,macos,Ios,Objective C,Multithreading,Macos,{ __弱id weakSelf=自我 for (ANKChannel *channel in self.channelArray) { NSLog(@"channels %@",channel); NSLog(@"channel last message %@",channel.latestMessageID); [[ClientManager currentClient] fetchMessageWithI
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)PopulateTextView:(NSString*)消息
{
}
这就是我现在所处的位置,在我所得到的帮助下,我的方法是这样的。self.channelTextViewArray返回nil并导致崩溃,因为从未调用populateTextViews(NSString*)消息
有什么想法吗?如果
ClientManager
调用是异步的,那么populateTextViews
方法将在异步调用返回之前完成,这就是为什么不能使用其完成块中设置的值
要么把
NSMutableAttributedString *postText = [[NSMutableAttributedString alloc] initWithString:messageText];
…在完成块内,或在获得messageText后调用完成块内的方法。这样,您也不必声明_块变量
如果要进行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;
}
好的,我试一下。我调用了块内的另一个方法,但是当我设置断点时,块内的内容就不再被调用了。我在街区里做了这样的事。。。。[self-populateTextViewWithString:messageText];编辑答案以查看是否有帮助。等一下。刚回家,我会尽快试试这个。非常感谢大家的帮助,用我更新的代码来回答我的原始问题。由于textViewArray返回nil,仍然会发生崩溃。我的填充TextView的方法从未在完成块内被调用。当然,它不起作用,因为您的逻辑有一个“小”问题:在
NSLog
在块外运行后,您想要在块范围之外获取的信息将可用。您只需要同步线程以实现所需,但在块完成之前不应阻塞主线程。也许,你需要使用不同的代码模式,而不是你已经使用。我是一个自学成才的程序员,只有8个月的经验,所以我不知道一切,但我感谢你的帮助。对您所谈论的代码模式有什么建议吗?请通过GitHub
或Bitbucket
将源代码链接发送给我,我会查看一下。
- (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;
}