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

Posted

技术标签:

【中文标题】IOS/Objective-C:从完成块中检索 NSArray【英文标题】:IOS/Objective-C: Retrieve NSArray from completion block 【发布时间】:2018-02-21 15:37:06 【问题描述】:

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

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

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

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

问题是我不知道块何时完成所以如果我只是尝试访问 self.reminders 在调用上述方法后会出现在视图中,它返回空大概是因为块尚未完成我想要一些方法当我知道该块已完成以消除竞争条件时设置 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 中的完成块永远不会触发,所以出了点问题。

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

【问题讨论】:

为什么不在self.reminders =remindersArray; [self someMethodUsingReminders];这样的设置之后调用你想要执行的方法如果你想让它在主线程上然后将调用包装在dispatch_async中并传递主线程 【参考方案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 被释放时,确保移除观察者,否则你可能会崩溃

【讨论】:

以上是关于IOS/Objective-C:从完成块中检索 NSArray的主要内容,如果未能解决你的问题,请参考以下文章

从 iOS 中的私钥派生的证书(Objective-C)

IOS / Objective-C:测试图像是不是存在[重复]

IOS/objective-c/core-data:如何从相关实体获取属性

IOS/Objective-C:调用完成块的语法

使用 Web API 检索块中的文件数据以在浏览器中显示 (WIP)

Swift - 从完成块中解除视图控制器