NSOperationQueue队列waitUntilAllOperationsAreFinished挂起

时间:2010-07-29 10:20:47

标签: iphone multithreading nsoperation

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

类似于链接线程调用:

  1. UI线程 - >创建BG线程
  2. BG线程 - >调用XML服务并获得结果
  3. UI线程 - >更新BG线程操作成功的UI
  4. BG线程 - >触发操作的第2部分
  5. 全部加载应用。

    问题是我的第一个BG Thread操作似乎永远不会结束。在第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];
    }
    

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

    感谢您提供任何帮助 标记

1 个答案:

答案 0 :(得分:2)

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

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

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

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

结果,-invokeLoadingOfFriends:操作方法等待主线程的方法完成,这种方法永远不会发生,因为你用[queue waitUntilAllOperationsAreFinished]来阻止主线程。

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