Ios NSOperationQueue似乎降低了性能

Ios NSOperationQueue似乎降低了性能,ios,grand-central-dispatch,nsoperation,nsoperationqueue,Ios,Grand Central Dispatch,Nsoperation,Nsoperationqueue,我不熟悉NSOperationQueue,但在当前项目中,我需要一种在异步操作超时时取消该操作的方法。我的原始代码使用GCD和works。这是: dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0),^{ rg = [[RiverGauge alloc] initWithStationInfo:[station id] forHistoryInHours:48 inThisFormat:nil]

我不熟悉NSOperationQueue,但在当前项目中,我需要一种在异步操作超时时取消该操作的方法。我的原始代码使用GCD和works。这是:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0),^{
    rg = [[RiverGauge alloc] initWithStationInfo:[station id] forHistoryInHours:48 inThisFormat:nil];
    dispatch_async(dispatch_get_main_queue(), ^{
        [hud removeFromSuperview];
        UIStoryboard *sb = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
        GaugeViewController *vc = [sb instantiateViewControllerWithIdentifier:@"GaugeDetailViewController"];
        [vc setRiverGauge:rg];
        [self.navigationController pushViewController:vc animated:YES];
    });
});
RiverGauge是一种网络操作,可能需要很长时间,特别是如果用户在农村地区。我看到的大多数帖子都建议将其移动到NSOperationQueue中。我的工作如下:

NSOperationQueue *queue = [NSOperationQueue new];
NSInvocationOperation *op = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(getGaugeDetail:) object:[station id]];
[queue addOperation:op];
在getGaugeDetail方法(在选择器参数中)中,我有以下代码:

RiverGauge *rg = [[RiverGauge alloc] initWithStationInfo:gaugeIdentifier forHistoryInHours:48 inThisFormat:nil];
UIStoryboard *sb = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
GaugeViewController *vc = [sb instantiateViewControllerWithIdentifier:@"GaugeDetailViewController"];
[vc setRiverGauge:rg];
[self.navigationController pushViewController:vc animated:YES];
当使用GCD执行此操作时,它会通过快速internet连接快速响应。但是,使用NSOperationQueue时,相同的操作需要几秒钟。然而,返回的数据是准确的。再说一遍,我对NSOperationQueue不是很熟悉。有什么建议吗


谢谢

在使用NSOperationQueue的代码中,您似乎正在NSOperationQueue中进行UI更改,这可能是在主线程以外的线程上执行这些更改。有时,当您在主线程之外与UIKit元素交互时,它们要么工作不正常,要么在结果出现之前存在明显的延迟。所以我的猜测是,您看到了在错误线程上进行UI更改的效果


尝试在主线程上执行UIKit,看看它是否能解决您的问题。您可能可以继续使用GCD来完成此操作。

在使用NSOperationQueue时的代码中,您似乎正在NSOperationQueue中进行UI更改,这可能是在主线程以外的线程上执行这些更改。有时,当您在主线程之外与UIKit元素交互时,它们要么工作不正常,要么在结果出现之前存在明显的延迟。所以我的猜测是,您看到了在错误线程上进行UI更改的效果


尝试在主线程上执行UIKit,看看它是否能解决您的问题。您可能可以继续使用GCD来完成此操作。

在使用NSOperationQueue时的代码中,您似乎正在NSOperationQueue中进行UI更改,这可能是在主线程以外的线程上执行这些更改。有时,当您在主线程之外与UIKit元素交互时,它们要么工作不正常,要么在结果出现之前存在明显的延迟。所以我的猜测是,您看到了在错误线程上进行UI更改的效果


尝试在主线程上执行UIKit,看看它是否能解决您的问题。您可能可以继续使用GCD来完成此操作。

在使用NSOperationQueue时的代码中,您似乎正在NSOperationQueue中进行UI更改,这可能是在主线程以外的线程上执行这些更改。有时,当您在主线程之外与UIKit元素交互时,它们要么工作不正常,要么在结果出现之前存在明显的延迟。所以我的猜测是,您看到了在错误线程上进行UI更改的效果

尝试在主线程上执行UIKit,看看它是否能解决您的问题。您可能可以继续使用GCD来完成此任务。

而不是

[self.navigationController pushViewController:vc animated:YES]; 
您可以尝试以下方法:

[self.navigationController performSelectorOnMainThread:@selector(someMethod) withObject:<#(id)#> waitUntilDone:NO];

-(void)someMethod
{
//pushViewController:animated: //and other stuffs
}
我不知道除了主线程之外,在第二个线程中你到底想做什么,但是你必须记住的唯一一件事是你必须将主线程与其他线程分开。无论何时处理UI或更新UI,都必须在主线程中完成所有这些工作。其余的操作和后台内容可以由单独的线程使用NSOperationQueue来处理。否则,您的UI可能会冻结。 请让我知道它是否有效。谢谢:):)

代替

[self.navigationController pushViewController:vc animated:YES]; 
您可以尝试以下方法:

[self.navigationController performSelectorOnMainThread:@selector(someMethod) withObject:<#(id)#> waitUntilDone:NO];

-(void)someMethod
{
//pushViewController:animated: //and other stuffs
}
我不知道除了主线程之外,在第二个线程中你到底想做什么,但是你必须记住的唯一一件事是你必须将主线程与其他线程分开。无论何时处理UI或更新UI,都必须在主线程中完成所有这些工作。其余的操作和后台内容可以由单独的线程使用NSOperationQueue来处理。否则,您的UI可能会冻结。 请让我知道它是否有效。谢谢:):)

代替

[self.navigationController pushViewController:vc animated:YES]; 
您可以尝试以下方法:

[self.navigationController performSelectorOnMainThread:@selector(someMethod) withObject:<#(id)#> waitUntilDone:NO];

-(void)someMethod
{
//pushViewController:animated: //and other stuffs
}
我不知道除了主线程之外,在第二个线程中你到底想做什么,但是你必须记住的唯一一件事是你必须将主线程与其他线程分开。无论何时处理UI或更新UI,都必须在主线程中完成所有这些工作。其余的操作和后台内容可以由单独的线程使用NSOperationQueue来处理。否则,您的UI可能会冻结。 请让我知道它是否有效。谢谢:):)

代替

[self.navigationController pushViewController:vc animated:YES]; 
您可以尝试以下方法:

[self.navigationController performSelectorOnMainThread:@selector(someMethod) withObject:<#(id)#> waitUntilDone:NO];

-(void)someMethod
{
//pushViewController:animated: //and other stuffs
}
我不知道除了主线程之外,在第二个线程中你到底想做什么,但是你必须记住的唯一一件事是你必须将主线程与其他线程分开。无论何时处理UI或更新UI,都必须在主线程中完成所有这些工作。其余的操作和后台内容可以由单独的线程使用NSOperationQueue来处理。否则,您的UI可能会冻结。
请让我知道它是否有效。谢谢:):)

首先,您不需要从GCD将其移动到NSOperationQueue中。这没有道理。问题在于RiverGauge-initWithStationInfo:forHistoryInHours:inThisFormat:方法本身

RiverGauge是一种网络操作,可能需要很长时间,特别是如果用户在农村地区

如果你想取消这个方法,你必须在方法中实现一些可以取消的东西,或者完全重写。将网络操作与方法分离,并使用