如何在函数中立即执行块?
How to execute a block immediately in a function?
我在网上搜索,但我发现的不是我想要的。
我有一个函数,里面有一个块,这个函数 return 在对块进行处理之前。所以我的函数 return nil...
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;
}
我可以使用哪种方法在我的函数中立即执行一个块?
非常感谢大家!!!
而不是 return 像 this.You 这样的值可以使函数不 return 任何东西并以块作为参数。
该块会将值作为参数。
将您现有的代码更改为以下代码
-(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);
}];
干杯。
您正在使用的 Google 库被设计为异步的 - 它正在调用 Web 服务,它们可能需要任意长的时间才能完成。在考虑同步解决方案时,您必须考虑到这一点 - 您可能会阻塞任意长的时间。
最适合您的解决方案是重新设计您的代码,使其成为异步的。
如果您由于某种原因不能使您的代码异步,那么您可以使异步调用看起来是同步的,但是您必须小心。本质上,您需要做的就是使用信号量:让异步调用信号量的回调块发出信号量,并在进行异步调用后等待信号量。 但是要使此工作正常,您需要知道您在信号量上等待的线程与将用于回调的线程不同——否则回调将被阻止。您需要确定 Google 库对将调用回调的线程做出哪些保证,并适当地编写您的代码。
如果这一切听起来太复杂,请回到第一个建议 - 让您的代码异步!
HTH
我在网上搜索,但我发现的不是我想要的。
我有一个函数,里面有一个块,这个函数 return 在对块进行处理之前。所以我的函数 return nil...
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;
}
我可以使用哪种方法在我的函数中立即执行一个块?
非常感谢大家!!!
而不是 return 像 this.You 这样的值可以使函数不 return 任何东西并以块作为参数。 该块会将值作为参数。
将您现有的代码更改为以下代码
-(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);
}];
干杯。
您正在使用的 Google 库被设计为异步的 - 它正在调用 Web 服务,它们可能需要任意长的时间才能完成。在考虑同步解决方案时,您必须考虑到这一点 - 您可能会阻塞任意长的时间。
最适合您的解决方案是重新设计您的代码,使其成为异步的。
如果您由于某种原因不能使您的代码异步,那么您可以使异步调用看起来是同步的,但是您必须小心。本质上,您需要做的就是使用信号量:让异步调用信号量的回调块发出信号量,并在进行异步调用后等待信号量。 但是要使此工作正常,您需要知道您在信号量上等待的线程与将用于回调的线程不同——否则回调将被阻止。您需要确定 Google 库对将调用回调的线程做出哪些保证,并适当地编写您的代码。
如果这一切听起来太复杂,请回到第一个建议 - 让您的代码异步!
HTH