简体   繁体   English

iOS / Objective-C:从完成块中检索NSArray

[英]IOS/Objective-C: Retrieve NSArray from completion block

I am trying to retrieve an array of EKReminders from a completion block of a method. 我正在尝试从方法的完成块检索EKReminders数组。 The method returns the array I desire. 该方法返回我想要的数组。 However, I can't find a good way to obtain it back on the main thread at known time such that that I know the block has completed. 但是,我找不到在已知时间在主线程上重新获得它的好方法,以至于我知道该块已完成。

To retrieve EKReminders , Apple requires a completion block approach (in contrast to EKEvents .) So my fetch code contains the following: 要检索EKReminders ,Apple需要使用完成块方法(与EKEvents相反。)因此,我的提取代码包含以下内容:

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

The above code successfully runs and places reminders in the ivar once finished.. 上面的代码成功运行,并在完成后在ivar中放置提醒。

The problem is I don't know when the block completes so if I merely try to access self.reminders in viewwillappear after callng the above method, it returns empty presumably because the block has not yet completed I would like some way to set the ivar when I know that the block has completed to eliminate the race condition. 问题是我不知道该块何时完成,因此如果我只是尝试访问self.reminders在view中会在调用上述方法后出现,它可能会返回空值,因为该块尚未完成,我想通过某种方式来设置ivar当我知道该区块已完成以消除竞争状况时。

A number of answers on SO for how to retrieve a value form a completion block recommend passing in a completion block to the method as follows: 关于如何从完成块中检索值的一些关于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);
    }];

When I try this, the completion block in viewwillappear never fires so something is going wrong. 当我尝试此操作时, viewwillappear不会出现完成块,因此出现了问题。

Would appreciate any suggestions on how to successfully retrieve at a known point in time an array retrieved within a completion block. 将感谢有关如何在已知时间点成功检索在完成块内检索到的数组的任何建议。

There are various different ways to achieve that. 有多种不同的方法可以实现这一目标。 You can either set up a key value observer or a NSNotification or do your necessary actions in your setter method of your reminders object or even just call your necessary actions in that completionHandler block. 您可以设置键值观察器或NSNotification,也可以在reminders对象的setter方法中执行必要的动作,甚至可以在该completeHandler块中调用必要的动作。

Calling out from the handler block 从处理程序块中调出

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

Key Value Observer Method 键值观察者方法
When your view loads you can add a key value observer like this: 加载视图时,您可以像这样添加一个键值观察器:

[self addObserver:self
       forKeyPath:@"self.reminders"
          options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld
          context:nil];

And implement this method: 并实现此方法:

-(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
      }
}

Make sure to remove observers when your viewController is dealloacted or you may get a crash 取消viewController时,请确保删除观察者,否则可能会崩溃



声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM