NSOperation在解析数据时绘制UI?

时间:2010-01-22 11:12:39

标签: iphone cocoa-touch multithreading nsurlconnection nsoperation

希望你们能帮助我:)。

在主线程中,我创建了一个NSOperation并将其添加到队列中。 该操作的作用是使用NSURLConnection连接到数据服务器,保存receivedData并解析它。

Operation.m

- (void)start
{
    NSLog(@"opeartion for <%@> started.", [cmd description]);

    [self willChangeValueForKey:@"isExecuting"];
    _isExecuting = YES;
    [self didChangeValueForKey:@"isExecuting"];

    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:_url];

    [request setHTTPMethod:@"POST"];
    [request setValue:[NSString stringWithFormat:@"multipart/form-data; boundary=%@", m_BOUNDARY] forHTTPHeaderField:@"Content-Type"];
    [request setHTTPBody:_postData];

    _connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];

    if (_connection == nil)
        [self finish];
}

然后在这个NSURL委托方法中,我解析了刚从服务器收到的数据。

Operation.m

- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
    [self parseItems];
}

在数据中,我可以找到一些项目,比如我发送到主线程的screenItem,CellItem,TextItem,以便在到达时绘制它们。 (如果itemTable到达,我创建一个UITableView,或者如果itemWeb到达,我创建一个UIWebView)

使用它将项目发送到主线程:

Operation.m

- (void) parseItems 
{
    while ([_data length] > 0)
    {
        NSInteger type = [self _readByte];

        switch (type) 
        {
            case SCREEN:
            {
                [self _send: [self _readScreen]];
                break;
            } 
            case CELL:
            {
                [self _send: [self _readCell]];
                break;
            } 

            // ... A lot of different items
        }
    }
}

- (void)_send:(CItem*)_item
{
    [[NSNotificationCenter defaultCenter] postNotificationName:@"newItem" object:_item];
}

然后在通知接收器中:

AppDelegate.m

- (void) _newItemArrived:(NSNotification *) notification
{
    [self performSelectorOnMainThread:@selector(processItem:) withObject:[notification object] waitUntilDone:NO];
}

我的问题是,在NSOperation完成之前,UI不会被绘制。我认为NSOpertion是一个不同的线程,不会阻止主线程,但相信这就是正在发生的事情。

此问题的一些提示?

非常感谢您的阅读!

2 个答案:

答案 0 :(得分:0)

您使用的是NSOperationQueue吗?

查看问题this answerNSOperation blocks UI painting?,了解如何使用来自另一个线程上异步运行的NSOperation的通知更新UI的简单示例。

更新

  1. NSURLConnection通过委托支持异步连接。你应该用它。如果您有特定问题,则应描述这些问题。
  2. 查看ASIHTTPRequest库。
  3. 如果您真的想使用这种方法,可以尝试同步运行NSURLConnection(使用类方法sendSynchronousRequest:returningResponse:error:)。由于连接是在后台线程,您的应用程序将保持响应。但是,在收到所有数据之前,您将无法更新任何内容。

答案 1 :(得分:0)

所以我知道这是一个非常古老的问题,但我遇到了同样的问题,经过几个小时的文档和博客后,我在Wim Haanstra的这篇文章中找到了一个很好的解决方案http://www.depl0y.com/?p=345

将你的NSOperation置于一个无限循环中直到你得到数据为止应该可以做到这一点!