首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在设备为iPhone12的iOS15上阻止运行循环的主线程失败?

在设备为iPhone12的iOS15上阻止运行循环的主线程失败?
EN

Stack Overflow用户
提问于 2021-09-24 09:05:00
回答 1查看 617关注 0票数 1

在我的项目中,我使用runloop阻塞主线程来实现获取UIAlertController的用户点击结果。以下是测试视图控制器.h和视图控制器.m的代码:

代码语言:javascript
复制
#import <UIKit/UIKit.h>
@interface ViewController : UIViewController
@end


#import "ViewController.h"
@interface ViewController ()    
@end

static NSInteger kButtonIndex = -1;

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    BOOL result = [self test];
    NSLog(@"Result: %d",result);
}

- (BOOL)test{
    kButtonIndex = -1;
    
    NSLog(@"000");

    UIAlertController *alerVC = [UIAlertController alertControllerWithTitle:@"Alert" message:@"Message" preferredStyle:UIAlertControllerStyleAlert];
    [alerVC addAction:[UIAlertAction actionWithTitle:@"Ok" style:(UIAlertActionStyleDestructive) handler:^(UIAlertAction * _Nonnull action) {
        kButtonIndex = 1;
    }]];
    [alerVC addAction:[UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
        kButtonIndex = 0;
    }]];

    NSLog(@"111");

    [self presentViewController:alerVC animated:YES completion:^{}];

    NSLog(@"222");

    while (kButtonIndex == -1) {
        [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.1f]];
    }

    if (kButtonIndex == 1) {
        return YES;
    }
    if (kButtonIndex == 0) {
        return NO;
    }

    return NO;
}
@end

在具有任何iOS版本的device iPhone 11或更早的设备上,一旦您轻触屏幕,UIAlertViewController将显示,如果您单击Ok按钮,控制台日志应如下所示:

代码语言:javascript
复制
2021-09-24 16:51:04.146063+0800 TestAlert[1520:46901] 000
2021-09-24 16:51:04.148558+0800 TestAlert[1520:46901] 111
2021-09-24 16:51:04.165442+0800 TestAlert[1520:46901] 222
2021-09-24 16:51:05.774194+0800 TestAlert[1520:46901] Result: 1

但是,如果在装有iOS 15的device iPhone 12或更高版本设备上,一旦轻触屏幕,UIAlertViewController将不会显示,控制台日志应如下所示:

代码语言:javascript
复制
2021-09-24 16:51:04.146063+0800 TestAlert[1520:46901] 000
2021-09-24 16:51:04.148558+0800 TestAlert[1520:46901] 111
2021-09-24 16:51:04.165442+0800 TestAlert[1520:46901] 222

下面的代码似乎不再起作用了:

代码语言:javascript
复制
while (kButtonIndex == -1) {
    [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.1f]];
}

有没有人遇到过这个问题?谢谢!

额外:我们的项目使用Cordova和UIWebView,这个应用程序中的一些远程h5页面来自其他公司(如果我们将webview更改为WKWebView,这些公司需要更新他们的js文件,如cordova.js,这是一项艰巨的工作,所以我们留在UIWebView)……在UIWebView中,一些用户说js confirm()函数在iOS15上不再显示模式视图,我试了很多,发现UIWebView中的js confirm()函数呈现了一个UIAlertController。我试着像这样重写UIWebView确认实现,它在除iPhone 12 iOS15之外的任何设备上都工作得很好:

代码语言:javascript
复制
#import <UIKit/UIKit.h>
@interface UIWebView (Alert)
@end

#import "UIWebView+Alert.h"

@implementation UIWebView (Alert)

static NSInteger kButtonIndex = -1;

- (BOOL)webView:(UIWebView *)sender runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(id)frame{
    kButtonIndex = -1;

    UIAlertController *alerVC = [UIAlertController alertControllerWithTitle:@"Alert" message:message preferredStyle:UIAlertControllerStyleAlert];
    [alerVC addAction:[UIAlertAction actionWithTitle:@"Ok" style:(UIAlertActionStyleDestructive) handler:^(UIAlertAction * _Nonnull action) {
        kButtonIndex = 1;
    }]];
    [alerVC addAction:[UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
        kButtonIndex = 0;
    }]];

    [[self topViewController] presentViewController:alerVC animated:YES completion:^{}];

    while (kButtonIndex == -1) {
        [[NSRunLoop mainRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.1f]];
    }

    if (kButtonIndex == 1) {
        return YES;
    }
    if (kButtonIndex == 0) {
        return NO;
    }

    return NO;
}

@end

实际上,上面的代码与我问题中的最前面的代码几乎是一样的,如果有人可以提供帮助,你可以运行最前面的测试代码来重现问题。

EN

回答 1

Stack Overflow用户

发布于 2021-09-24 14:16:00

我们在iPhone 12上的iOS 15上的动画中遇到了同样的问题。我们使用[NSRunLoop mainRunLoop runUntilDate]来允许动画在继续执行主线程中的代码之前完成执行。但是,这在iPhone 12上的iOS 15上不起作用。即使当调用runUntilDate的时间超过动画持续时间时,动画也不会完成。这似乎只在运行iOS 15的iPhone 12设备上是一个问题。在模拟器、iPhone 11设备上,甚至在具有与iPhone 12相同处理器的iPad Air 4上,一切都工作正常。在调用runUntilDate时,通常在主线程上执行的UI代码似乎不能在iOS 15 / iPhone 12上执行。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69312354

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档