NSOperationQueue 似乎在完成时挂起几秒钟
我有一个自定义视图控制器,它实现了 UITableViewDataSource 和 UITableViewDelegate 协议。当我为表加载数据时(在 viewDidLoad
方法中),我创建一个 NSOperationQueue
和一个 NSInitationOperation
并将其添加到队列中。我抛出一个活动指示器,然后 viewDidLoad
退出。
用于操作的方法结束活动指示器动画。
我注意到,当操作完成时,在操作真正完成之前有 5-7 秒的暂停,即使通过 NSLog 看起来像是返回了操作的方法。
我尝试使用 Instruments 来找出暂停发生的位置,但我无法从中看出,因为我的大部分 CPU 时间都花在系统库上。
编辑 这是一个缩写版本:
@implementation MyViewController
@synthesize ...
- (void)viewDidLoad {
[super viewDidLoad];
self.opsQueue = [[NSOperationQueue alloc] init];
NSInvocationOperation *aiStartOp = [[[NSInvocationOperation alloc]
initWithTarget:self
selector:@selector(showActivityIndicators)
object:nil] autorelease];
[self.opsQueue addOperation:aiStartOp];
NSInvocationOperation *dataOp = [[[[NSInvicationOperation alloc]
initWithTarget:self
selector:@selector(dataUpdate)
object:nil] autorelease];
[dataOp addDependency aiStartOp];
[self.opsQueue addOperation:dataOp];
NSInvicationOperation *aiStopOp = [[[NSInvicationOperation alloc]
initWithTarget:self
selector:@selector(hideActivityIndicators)
object:nil] autorelease];
[aiStopOp addDependency:dataOp];
[self.opsQueue addOperation:aiStopOp];
}
/* other stuff */
@end
需要明确的是,队列中的最后一个操作是这样的:
- (void)hideActivityIndicators {
DLog(@"hiding activity indicator");
self.portraitChartProgressView.hidden = YES;
[self.portraitChartProgressIndicator stopAnimating];
self.landscapeProgressView.hidden = NO;
[self.landscapeProgressIndicator startAnimating];
}
我在日志中看到的是上述日志消息的输出,然后停顿了 5 秒,最后是视图其上的指示器被隐藏。
有什么想法吗?
I have a custom view controller that implements the from UITableViewDataSource
and UITableViewDelegate
protocols. When I load data for my table (in my viewDidLoad
method), I create a NSOperationQueue
and a NSInvocationOperation
and add it to the queue. I throw up an activity indicator, and viewDidLoad
exits.
The method used for the operation ends the activity indicator animation.
I have noticed that when the operation completes, there is a 5-7 second pause before the operation really completes, even though by NSLog it looks like the operation's method returned.
I have tried to use Instruments to figure out where the pause is happening, but I can't tell from it because most of my CPU time is spent in system libraries.
Edit
Here's an abbreviated version:
@implementation MyViewController
@synthesize ...
- (void)viewDidLoad {
[super viewDidLoad];
self.opsQueue = [[NSOperationQueue alloc] init];
NSInvocationOperation *aiStartOp = [[[NSInvocationOperation alloc]
initWithTarget:self
selector:@selector(showActivityIndicators)
object:nil] autorelease];
[self.opsQueue addOperation:aiStartOp];
NSInvocationOperation *dataOp = [[[[NSInvicationOperation alloc]
initWithTarget:self
selector:@selector(dataUpdate)
object:nil] autorelease];
[dataOp addDependency aiStartOp];
[self.opsQueue addOperation:dataOp];
NSInvicationOperation *aiStopOp = [[[NSInvicationOperation alloc]
initWithTarget:self
selector:@selector(hideActivityIndicators)
object:nil] autorelease];
[aiStopOp addDependency:dataOp];
[self.opsQueue addOperation:aiStopOp];
}
/* other stuff */
@end
Just to be clear, the last operation in the queue is this:
- (void)hideActivityIndicators {
DLog(@"hiding activity indicator");
self.portraitChartProgressView.hidden = YES;
[self.portraitChartProgressIndicator stopAnimating];
self.landscapeProgressView.hidden = NO;
[self.landscapeProgressIndicator startAnimating];
}
What I see in the log is the output of the above log message, followed by a pause of 5 seconds, and then finally followed by the view with the indicator on it being hidden.
Any ideas?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
所有UI事件、绘图等都需要在主线程上执行。
您可以使用类似以下内容将调用转发到主线程。
编辑”
现在我看得更仔细了,您可能不需要做的一件事是通过添加到
NSOperationQueue
来启动和停止“加载”视图。可能您在队列中需要做的唯一事情是数据更新,然后在数据操作完成时发布通知和委托来更新您的视图。 iphone/library/samplecode/TopSongs/Introduction/Intro.html" rel="nofollow noreferrer">TopSongs 示例项目很好地演示了这一点。到主线程的转发语句基于 AppDelegate.m 文件中的代码在样本中。
All UI events, drawing etc. need to be performed on the main thread.
You can forward calls to the main thread using something like the following.
EDIT"
Now that I look a little more carefully, one thing you probably don't need to do is start and stop the "loading" views by adding to an
NSOperationQueue
. Likely the only thing that you need to do in in the queue is the data update, then post notifications and delegation to update your views when the data operation is complete.The TopSongs sample project demonstrates this very well. The forwarding statement to the main thread is based on code in the AppDelegate.m file in the sample.