objective c 等待另一个委托的块

objective c block that waits for another delegate

我有一个 watchkit 应用程序在 iphone 应用程序上调用 viewcontroller。我有一个网络连接代表。我正在尝试使用一个块,这样我就不会将我的 AppDelegate 和我的视图控制器紧密结合在一起。委托完成后如何通知我的区块?

ViewController.m

-(void)getWatchDataWithCompletion:(void(^)(BOOL gotData))completion{
   [self setUpAppForWatch];
   completion(YES);
}

-(void)finishedMessageParse:(NSMutableData *)messageData{
   //the delegate is finish tell the block completion is done.

}

-(void)setUpAppForWatch{
   [network call];
}

AppDelegate.m

-(void)application:(UIApplication *)application handleWatchKitExtensionRequest:(NSDictionary *)userInfo reply:(void (^)
(NSDictionary *))reply{

[vc getWatchDataWithCompletion:^(BOOL gotData){
    if (gotData){
       //I'm done reply dictionary
       reply(@{@"data":serlizedData})
}];

共有三种可能的方法。

;tldr - 参考第三个。否则 - 阅读所有内容,可能会有用。

第一个

使用私有串行队列来执行 finished... 方法和您的块的任务。如果 finished... 总是调用 before 块,它就足够了。如果没有 - 看看第二个

使用视图控制器的私有 @property dispatch_queue_t privateSerialQueue;

privateSerialQueue = dispatch_queue_create("PrivateQueue", DISPATCH_QUEUE_SERIAL);

不如这样用

-(void)getWatchDataWithCompletion:(void(^)(BOOL gotData))completion{
    [self setUpAppForWatch];
    dispatch_async(privateSerialQueue, ^(){
       completion(YES);
    });
}

-(void)finishedMessageParse:(NSMutableData *)messageData{
    dispatch_sync(privateSerialQueue, ^(void){
            //Here goes whatever you need to do in this method before block start
    });
    //the delegate is finish tell the block completion is done.
}

第二个

看看dispatch_semaphore_t。使其成为您的视图控制器 public 属性

@property (readonly) dispatch_semaphore_t semaphore

用起始值 0 创建它。如果 finished 有,它会让你在委托 finished... 方法和 运行 之前立即等待你的块 运行s在块之前已经完成。像这样

self.semaphore = dispatch_semaphore_create(0); 

那你可以这样用

-(void)finishedMessageParse:(NSMutableData *)messageData{
  //the delegate is finish tell the block completion is done.
  dispatch_semaphore_signal(self.semaphore);
}

[vc getWatchDataWithCompletion:^(BOOL gotData){
    if (gotData){
       //I'm done reply dictionary
       dispatch_semaphore_wait(vc.semaphore, DISPATCH_TIME_FOREVER);
       reply(@{@"data":serlizedData})
}];

第三个

写上面两个时我想到了 =) 前两者的某种组合

使用视图控制器的 private 属性 @property (readonly) dispatch_semaphore_t semaphore

以与第二个相同的方式初始化它(起始值为0)

self.semaphore = dispatch_semaphore_create(0); 

并像这样私下使用它

-(void)getWatchDataWithCompletion:(void(^)(BOOL gotData))completion{
    [self setUpAppForWatch];
    dispatch_semaphore_wait(self.semaphore, DISPATCH_TIME_FOREVER);
    completion(YES);
}

-(void)finishedMessageParse:(NSMutableData *)messageData{
  //the delegate is finish tell the block completion is done.
  dispatch_semaphore_signal(self.semaphore);
}

P。 S. Hope,它可以帮助您切入正题。有什么不明白的随时问

在viewcontroller中添加新的属性:

@property (nonatomic, strong) void(^completion)(BOOL gotData);


-(void)getWatchDataWithCompletion:(void(^)(BOOL gotData))completion{
   [self setUpAppForWatch];
   self.completion = completion;
}

-(void)finishedMessageParse:(NSMutableData *)messageData{
    if (self.completion){
        self.completion(YES);
    }
}