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

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