我有一个方法可以在应用变为活动状态时检查剪贴板:
- (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");
}
}];
}
答案 0 :(得分:1)
似乎 checkClipboard 方法在主线程中调用 valudateURL ,如下所示:
dispatch_async(dispatch_get_main_queue(), ^{
[self valudateURL];
});
因此,如果您希望 valudateURL 在这种情况下在非主线程中工作,则应该在没有dispatch_async的情况下调用它。
- 已编辑 -
是的,所以 getUserProfile:块在主线程中运行,如屏幕截图所示,这就是它阻止应用程序的原因。因此,如果您希望 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
});
}];
});
}];
}