applicationDidBecomeActive 方法阻塞了我的 UI

applicationDidBecomeActive method blocking my UI

我有一种方法可以在应用程序激活时检查剪贴板:

- (void)applicationDidBecomeActive:(UIApplication *)application {
    [[NSNotificationCenter defaultCenter] postNotificationName:@"reload" object:nil];
    dispatch_queue_t backgroundQueue = dispatch_queue_create("clipboardQueue", 0);
    dispatch_async(backgroundQueue, ^{
        [self checkClipboard];
    });
}

但该应用程序挂起的时间过长(似乎是剪贴板数据的正则表达式检查)- 我如何强制此进程在另一个线程上 运行?看来我的常规 GCD 方法似乎不起作用。

这是我挂机时主线程的截图:

这是它挂起的函数:

- (BOOL)validateUrl:(NSString *)candidate {
    NSString *urlRegEx = @"\b(?:(?:https?|ftp):\/\/)(?:\S+(?::\S*)?@)?(?:(?!10(?:\.\d{1,3}){3})(?!127(?:\.\d{1,3}){3})(?!169\.254(?:\.\d{1,3}){2})(?!192\.168(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\x{00a1}-\x{ffff}0-9]+-?)*[a-z\x{00a1}-\x{ffff}0-9]+)(?:\.(?:[a-z\x{00a1}-\x{ffff}0-9]+-?)*[a-z\x{00a1}-\x{ffff}0-9]+)*(?:\.(?:[a-z\x{00a1}-\x{ffff}]{2,})))(?::\d{2,5})?(?:\/[^\s]*)?\b(\/)?";
    NSPredicate *urlTest = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", urlRegEx];
    return [urlTest evaluateWithObject:candidate];
}

这是我的 checkClipboard 方法:

- (void)checkClipboard {
    [[ProfileManager sharedInstance] getUserProfile:^(BOOL done, Profile *profile, NSInteger status) {
        if (done) {
            NSURL *lastUrl = [NSURL URLWithString:[[NSUserDefaults standardUserDefaults] stringForKey:@"clipboard"]];
            UIPasteboard *pb = [UIPasteboard generalPasteboard];
            NSMutableString *urlString = pb.string.mutableCopy;

            if (urlString.length) {
                if (![urlString containsString:@"http"]) {
                    urlString = [NSString stringWithFormat:@"http://%@",urlString].mutableCopy;
                }
                BOOL urlValidate = [self validateUrl:urlString];
                if (urlValidate) {
                    if (!pb.string.length || [urlString isEqualToString:lastUrl.absoluteString] || !urlValidate) {
                        return;
                    } else {

                        dispatch_async(dispatch_get_main_queue(), ^{

                           //popup toast code

                        });
                    }
                }
            }

        } else {
            NSLog(@"Not Logged In");
        }
    }];

}

似乎 checkClipboard 方法在主线程中调用了 valudateURL,像这样:

dispatch_async(dispatch_get_main_queue(), ^{
        [self valudateURL];
});

所以如果你想让 valudateURL 在这种情况下在非主线程中工作,你应该在没有 dispatch_async.

的情况下调用它

-- 已编辑 --

是的,所以 getUserProfile: 在主线程中阻止 运行s,如您在屏幕截图中所见,这就是它阻止应用程序的原因。所以如果你想在后台 validateUrl:complete: 到 运行 ,你应该在那里用 dispatch_async 调用它,像这样:

- (void)checkClipboard {
    [[ProfileManager sharedInstance] getUserProfile:^(BOOL done, Profile *profile, NSInteger status) {
 ...
    dispatch_queue_t backgroundQueue = dispatch_queue_create("clipboardQueue", 0);
    dispatch_async(backgroundQueue, ^{
        [self validateUrl:urlString complete:^(BOOL urlValidate) {
            ...
            dispatch_async(dispatch_get_main_queue(), ^{
               //popup toast code
            });
        }];
    });
 }];
}