我正在尝试从方法的完成 block 中检索 EKReminders
数组。该方法返回我想要的数组。但是,我找不到在已知时间在主线程上获取它的好方法,这样我就知道该 block 已完成。
要检索 EKReminders
,Apple 需要一个完成 block 方法(与 EKEvents
不同。)所以我的获取代码包含以下内容:
-(void) fetchReminders{
[self.eventStore fetchRemindersMatchingPredicate:predicate completion:^(NSArray *reminders) {
self.reminders = reminders;
}];
}
上面的代码成功运行并在完成后将提醒放入 ivar 中..
问题是我不知道该 block 何时完成,所以如果我只是尝试在调用上述方法后访问 viewwillappear 中的 self.reminders,它可能会返回空,因为该 block 尚未完成我想要一些方法当我知道 block 已完成以消除竞争条件时设置 ivar。
关于如何从完成 block 中检索值的许多答案建议将完成 block 传递给方法,如下所示:
//change above method to
-(void) fetchReminders withCompletion:(void (^)(NSArray *reminders))completion; {
and call it in viewwillappear with:
[self fetchReminders withCompletion:^(NSArray* reminders) {
self.reminders =remindersArray;
NSLog(@"remindersArray in viewwillappear%@",remindersArray);
}];
当我尝试这个时,viewwillappear
中的完成 block 永远不会触发,所以出了点问题。
对于如何在已知时间点成功检索完成 block 中检索到的数组的任何建议,我们将不胜感激。
最佳答案
有多种不同的方法可以实现这一目标。
您可以设置一个键值观察器或 NSNotification,或者在您的 reminders
对象的 setter 方法中执行必要的操作,甚至可以在该 completionHandler block 中调用您的必要操作。
从处理程序 block 中调用
-(void) fetchReminders{
[self.eventStore fetchRemindersMatchingPredicate:predicate
completion:^(NSArray *reminders) {
dispatch_async(dispatch_get_main_queue(), ^{
self.reminders = reminders;
[self doWhatYaGottaDoMethod];
});
}];
}
键值观察法
当您的 View 加载时,您可以像这样添加一个键值观察器:
[self addObserver:self
forKeyPath:@"self.reminders"
options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld
context:nil];
并实现这个方法:
-(void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary *)change
context:(void *)context{
if([keyPath isEqualToString:@"self.reminders"]){
//You got your reminders, do what you gotta do
}
}
确保在你的 viewController 被释放时移除观察者,否则你可能会崩溃
关于IOS/objective-C : Retrieve NSArray from completion block,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48909794/