等待另一位代表的目标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希望,它可以帮助您达到目的。 随意问一些不清楚的事情