gpt4 book ai didi

ios - 从 block 中返回一个值

转载 作者:行者123 更新时间:2023-12-01 17:53:05 25 4
gpt4 key购买 nike

我一直在阅读 Objectice-C block ,因为我最近越来越多地遇到它们。我已经能够解决我的大部分异步 block 执行问题,但是我发现了一个我似乎无法解决的问题。我想过做一个__block BOOL返回什么,但我知道方法末尾的return语句将在 block 完成运行之前执行。我也知道我不能在 block 内返回值。

- (BOOL)shouldPerformSegueWithIdentifier:(NSString *)identifier sender:(id)sender {

if ([identifier isEqualToString:@"Reminder Segue"]) {

eventStore = [[EKEventStore alloc] init];

[eventStore requestAccessToEntityType:EKEntityTypeReminder completion:^(BOOL granted, NSError *error) {

if (!granted) {

UIAlertView *remindersNotEnabledAlert;
remindersNotEnabledAlert = [[UIAlertView alloc] initWithTitle:@"Reminders Not Enabled" message:@"In order for the watering reminder feature to function, please allow reminders for the app under the Privacy menu in the Settings app." delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil, nil];

//I would like to put a simple return NO statement here, but I know it is impossible
}
}];
}

return YES;
}

如何从 block 中创建简单的返回语句?

最佳答案

虽然直接的想法可能是使您的异步请求同步,但这很少是一个好主意,并且在这种情况下这样做可能会出现问题。尝试使异步方法同步几乎不是一个好主意。

而且,正如 smyrgl 指出的那样,“我不能只从 block 中返回一个值”的想法在直觉上很有吸引力,但是虽然您可以定义自己的返回值的 block (正如 Duncan 指出的那样),但您无法改变行为requestAccessToEntityType 以便它以这种方式返回一个值。它的异步模式固有的是,您必须对 block 内的授权状态采取行动,而不是在 block 之后。

因此,相反,我建议重构此代码。我建议您删除转场(可能是从“来自”场景中的控件启动的),而不是尝试依靠 shouldPerformSegueWithIdentifier 来确定是否可以通过调用此异步方法来执行转场。

相反,我将完全删除现有的 segue 并用 IBAction 方法替换它,该方法基于 requestAccessToEntityType 的结果以编程方式启动 segue。因此:

  • 将按钮(或其他)的segue移到下一个场景并删除此shouldPerformSegueWithIdentifier方法;
  • 在 View Controller 本身之间创建一个新的 segue(不是从“from”场景中的任何控件,而是在 View Controller 本身之间)并给这个 segue 一个 Storyboard ID(例如,参见屏幕快照 herehere );
  • 将控件连接到 IBAction 方法,您可以在该方法中执行此 requestAccessToEntityType ,如果获得批准,您将执行此 segue,否则会显示适当的警告。

    因此,它可能看起来像:
    - (IBAction)didTouchUpInsideButton:(id)sender
    {
    eventStore = [[EKEventStore alloc] init];

    [eventStore requestAccessToEntityType:EKEntityTypeReminder completion:^(BOOL granted, NSError *error) {

    // by the way, this completion block is not run on the main queue, so
    // given that you want to do UI interaction, make sure to dispatch it
    // to the main queue

    dispatch_async(dispatch_get_main_queue(), ^{
    if (granted) {
    [self performSegueWithIdentifier:kSegueToNextScreenIdentifier sender:self];
    } else {
    UIAlertView *remindersNotEnabledAlert;
    remindersNotEnabledAlert = [[UIAlertView alloc] initWithTitle:@"Reminders Not Enabled" message:@"In order for the watering reminder feature to function, please allow reminders for the app under the Privacy menu in the Settings app." delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
    [remindersNotEnabledAlert show];
    }
    });
    }];
    }
  • 关于ios - 从 block 中返回一个值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23506854/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com