NSOperationQueue 队列 waitUntilAllOperationsAreFinished 挂起

发布于 2024-09-12 03:23:26 字数 1412 浏览 1 评论 0原文

我有一个 iPhone 应用程序,在加载视图控制器时,我想调用 Web 服务,在后台线程上获取和解析 XML。然后在线程完成后更新 ui,然后触发另一个线程在另一个后台线程中执行第二个操作。

有点像链接线程调用:

  1. UI Thread ->创建BG线程
  2. BG线程->调用XML服务并获取结果
  3. UI Thread ->更新BG Thread操作成功的UI
  4. BG Thread ->触发操作的第 2 部分

所有加载应用程序。

问题是我的第一个 BG 线程操作似乎永远不会结束。我在第 2 步完成后添加了一个 waitUntilAllOperationsAreFinished 调用,只是为了看看发生了什么,而我的应用程序似乎从未超越该点。

这是基本的框架实现:

- (void) viewDidLoad 
{
    queue = [[NSOperationQueue alloc] init];
[queue setMaxConcurrentOperationCount:1];

    //other stuff

    [self loadFriendsInBackgroundThread];
}

- (void) loadFriendsInBackgroundThread
{   
    NSInvocationOperation *operation = [NSInvocationOperation alloc];
    operation = [operation initWithTarget:self selector:@selector(invokeLoadingOfFriends:) object: nil];

    [queue addOperation:operation];
[operation release];
}

- (void) invokeLoadingOfFriends: (id) obj
{
    //webservice calls and results

    [self performSelectorOnMainThread:@selector(invokeRefreshAfterLoadingFriends:) 
                       withObject:nil 
                    waitUntilDone:YES];
}

- (void) invokeRefreshAfterLoadingFriends: (id) obj
{
    //this line is where is hangs
    [queue waitUntilAllOperationsAreFinished];

    //never gets here
    [self refresh: NO];
}

关于为什么第一个线程调用似乎永远不会结束的任何想法?

感谢您可以提供的任何帮助 标记

I have an iphone app where on the loading of a view controller, I want to call a web service , get and parse XML all on the background thread. Then update the ui after the thread is done, then fire off another thread to do a secondard operation in another background thread.

Sort of like chaining threading calls:

  1. UI Thread -> Create BG Thread
  2. BG Thread -> Call XML service and get results
  3. UI Thread -> Update UI of the success of the BG Thread operation
  4. BG Thread -> Fire off part 2 of the operation

All on load of the app.

The issue is that my first, BG Thread operation never seems to end. I added in a waitUntilAllOperationsAreFinished call after step 2 is done, just to see whats going on and my app never seems to get past that point.

This is sort of the basic skeleton implementation:

- (void) viewDidLoad 
{
    queue = [[NSOperationQueue alloc] init];
[queue setMaxConcurrentOperationCount:1];

    //other stuff

    [self loadFriendsInBackgroundThread];
}

- (void) loadFriendsInBackgroundThread
{   
    NSInvocationOperation *operation = [NSInvocationOperation alloc];
    operation = [operation initWithTarget:self selector:@selector(invokeLoadingOfFriends:) object: nil];

    [queue addOperation:operation];
[operation release];
}

- (void) invokeLoadingOfFriends: (id) obj
{
    //webservice calls and results

    [self performSelectorOnMainThread:@selector(invokeRefreshAfterLoadingFriends:) 
                       withObject:nil 
                    waitUntilDone:YES];
}

- (void) invokeRefreshAfterLoadingFriends: (id) obj
{
    //this line is where is hangs
    [queue waitUntilAllOperationsAreFinished];

    //never gets here
    [self refresh: NO];
}

Any ideas as to why the first thread call never seems to end?

Thanks for any help you can give
Mark

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

懷念過去 2024-09-19 03:23:26

在这里,您在主线程上调用一个方法,该方法将等待直到被调用的方法完成 (waitUntilDone:YES):

[self performSelectorOnMainThread:@selector(invokeRefreshAfterLoadingFriends:) 
                   withObject:nil 
                waitUntilDone:YES];

然后调用 -invokeRefreshAfterLoadingFriends: 来保留主线程线程直到操作完成,因此该方法永远不会“完成”。来自 -waitUntilAllOperationsAreFinished

时,此方法会阻塞当前线程并等待接收者当前和排队的操作完成执行。

调用 结果,-invokeLoadingOfFriends: 操作方法等待主线程的方法完成,但这种情况永远不会发生,因为您使用 [queue waitUntilAllOperationsAreFinished] 暂停了主线程。

尝试将 waitUntilDone 设置为 NO 并查看这是否有助于操作完成。

Here, you are calling a method on the main thread that waits until the called method is done (waitUntilDone:YES):

[self performSelectorOnMainThread:@selector(invokeRefreshAfterLoadingFriends:) 
                   withObject:nil 
                waitUntilDone:YES];

You then call -invokeRefreshAfterLoadingFriends: which holds up the main thread until the operation finishes, so the method never gets "done". From the documentation for -waitUntilAllOperationsAreFinished:

When called, this method blocks the current thread and waits for the receiver’s current and queued operations to finish executing.

As a result, the -invokeLoadingOfFriends: operation method sits waiting for the main thread's method to finish, which never happens because you held up the main thread with [queue waitUntilAllOperationsAreFinished].

Try setting waitUntilDone to NO and see if this helps the operation finish.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文