0

我正在尝试EKReminders从方法的完成块中检索数组。该方法返回我想要的数组。但是,我找不到在已知时间在主线程上获取它的好方法,以便我知道该块已完成。

要检索EKReminders,Apple 需要一个完成块方法(与EKEvents. 相比)所以我的 fetch 代码包含以下内容:

-(void) fetchReminders{
[self.eventStore fetchRemindersMatchingPredicate:predicate completion:^(NSArray *reminders) {
        self.reminders = reminders;
 }];
}

上面的代码成功运行并在完成后将提醒放在 ivar 中。

问题是我不知道块何时完成所以如果我只是尝试访问 self.reminders in viewwillappear 在调用上述方法后,它返回空大概是因为块尚未完成我想要一些方法来设置 ivar当我知道该块已完成以消除竞争条件时。

关于如何从完成块中检索值的一些关于 SO 的答案建议将完成块传递给方法,如下所示:

//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永远不会触发,所以出了点问题。

将不胜感激有关如何在已知时间点成功检索完成块中检索到的数组的任何建议。

4

1 回答 1

1

有多种不同的方法可以实现这一目标。您可以设置键值观察器或 NSNotification 或在reminders对象的 setter 方法中执行必要的操作,甚至只需在该 completionHandler 块中调用您的必要操作。

从处理程序块中调用

-(void) fetchReminders{
   [self.eventStore fetchRemindersMatchingPredicate:predicate 
    completion:^(NSArray *reminders) {
        dispatch_async(dispatch_get_main_queue(), ^{
            self.reminders = reminders;
            [self doWhatYaGottaDoMethod];
        });
    }];
 }

键值观察者方法
当你的视图加载时,你可以像这样添加一个键值观察者:

[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 时删除观察者,否则可能会崩溃



于 2018-02-21T15:44:13.487 回答