如何立即在一个函数中执行一个块?

我在网上search,但我发现不是我所期望的。

我有一个块里面的函数,这个函数在处理之前返回到块中。 所以我的函数返回零…

NSString* returnTheFolder() { NSUserDefaults* userDefaults = [NSUserDefaults standardUserDefaults]; GTLServiceDrive *service; __block NSMutableDictionary* titlesAndIdentifiers; __block __strong NSString* rootFolder; __block NSArray* allIdentifiers; NSString* userDefaultValue = [userDefaults objectForKey:@"User1"]; titlesAndIdentifiers = [[NSMutableDictionary alloc]init]; service = [[GTLServiceDrive alloc] init]; service.authorizer = [GTMOAuth2ViewControllerTouch authForGoogleFromKeychainForName:KeychainForName clientID:ClientID clientSecret:ClientSecret]; GTLQueryDrive *query = [GTLQueryDrive queryForFilesList]; query.maxResults = 9999999; query.q = @"'root' in parents"; [service executeQuery:query completionHandler:^(GTLServiceTicket *ticket, GTLDriveFileList* files, NSError *error) { for (GTLDriveFile *folder in files) { if ([folder.mimeType isEqualToString:@"application/vnd.google-apps.folder"]) { [titlesAndIdentifiers setValue:folder.identifier forKey:folder.title]; allIdentifiers = [[NSArray alloc]initWithArray:[titlesAndIdentifiers allKeysForObject:userDefaultValue]]; rootFolder = [allIdentifiers objectAtIndex:0]; } } }]; return rootFolder; } 

我可以使用哪种方法在我的函数中立即执行块?

非常感谢大家!

您使用的Google库被devise为asynchronous – 它正在调用Web服务,并且可能需要很长时间才能完成。 在考虑同步解决scheme时,您必须考虑到这一点 – 您可能会阻塞任意长时间。

对你来说最好的解决scheme是重新devise你的代码,使它是asynchronous的。

如果由于某种原因无法使代码asynchronous,那么可以使asynchronous调用显示为同步,但是您必须小心 。 实质上你所要做的就是使用一个信号量:使asynchronous调用信号的callback阻塞信号量,并在asynchronous调用等待信号量之后。 然而,为了这个工作,你需要知道你在信号量上等待的线程不是用于callback的线程 – 否则callback将被阻塞。 您需要确定Google库会如何保证callback将被调用的线程,并适当地编写代码。

如果这听起来太复杂了,请回到第一个build议 – 使您的代码asynchronous!

HTH

而不是像这样返回一个值。你可以创build一个函数,它不返回任何东西,并把块作为参数。 该块将把该值作为参数。

将您现有的代码更改为下面的代码

 -(void)returnTheFolder:(void (^) (NSString *rootFolder))completion { NSUserDefaults* userDefaults = [NSUserDefaults standardUserDefaults]; GTLServiceDrive *service; __block NSMutableDictionary* titlesAndIdentifiers; __block __strong NSString* rootFolder; __block NSArray* allIdentifiers; NSString* userDefaultValue = [userDefaults objectForKey:@"User1"]; titlesAndIdentifiers = [[NSMutableDictionary alloc]init]; service = [[GTLServiceDrive alloc] init]; service.authorizer = [GTMOAuth2ViewControllerTouch authForGoogleFromKeychainForName:KeychainForName clientID:ClientID clientSecret:ClientSecret]; GTLQueryDrive *query = [GTLQueryDrive queryForFilesList]; query.maxResults = 9999999; query.q = @"'root' in parents"; [service executeQuery:query completionHandler:^(GTLServiceTicket *ticket, GTLDriveFileList* files, NSError *error) { for (GTLDriveFile *folder in files) { if ([folder.mimeType isEqualToString:@"application/vnd.google-apps.folder"]) { [titlesAndIdentifiers setValue:folder.identifier forKey:folder.title]; allIdentifiers = [[NSArray alloc]initWithArray:[titlesAndIdentifiers allKeysForObject:userDefaultValue]]; rootFolder = [allIdentifiers objectAtIndex:0]; completion(rootFolder); } } }]; } 

然后像下面这样打电话

 [self returnTheFolder:^(NSString *rootFolder){ NSLog(@"Root Folder = %@",rootFolder); }]; 

干杯。