等待另一位代表的目标c块

我有一个在iPhone应用程序上调用viewcontroller的watchkit应用程序。 我有一个网络连接代表。 我正在尝试使用一个块,这样我就不会将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}) }]; 

在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); } } 

有三种可能的方式。

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

第一

使用专用串行队列执行finished...方法和块的任务。 如果finished... ,它就足够finished...总是阻塞之前调用。 如果没有 – 看看第二个

使用private @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。 使其成为View Controler的公共属性

@property (readonly) dispatch_semaphore_t semaphore

使用起始值0创建它。它将让您等待,如果您的块在委托finished...之前运行,并立即运行,如果已完成,则在块之前已完成。 喜欢这个

 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}) }]; 

第三个

在写上面这两个时出现在我的脑海里=)前两个的某种组合

使用视图控制器的私有属性@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); } 

PS希望,它可以帮助您达到目的。 随意问一些不清楚的事情