开发者

NSOperation for drawing UI while parsing data?

Hope you guys can help me :)

In the main thread, I create a NSOperation and add it to a queue. What that operation do is connect to a data server with NSURLConnection, save the receivedData and parse it.

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];
}

Then in this NSURL delegate method I parse the data I've just received from server.

Operation.m

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

In the data, I can found items like, for instance, screenItem, CellItem, TextItem that I send to the main thread for drawing them while arriving. (I create a UITableView if an itemTable arrives, or I create a UIWebView if an itemWeb arrives)

Using this for sending item to main thread:

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];
}

Then in notification receiver:

AppDelegate.m

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

My problem is that the UI is not painted until NSOperation finish. I thought that NSOpertion, being a different thread, would not block the main thread, but believe that is what is happening.

Some tips for this issue?

Thanks a lot for reading!


Are you using NSOperationQueue?

Check out this answer to the question NSOperation blocks UI painting? for a simple example of how to update the UI with a notification from an NSOperation running asynchronously on another thread.

UPDATE

  1. NSURLConnection supports asynchronous connections by itself with a delegate. You should use this. If you have specific issue(s), you should describe those.
  2. Check out the ASIHTTPRequest library.
  3. If you really want to use this approach, you could trying running NSURLConnection synchronously (using the class method sendSynchronousRequest:returningResponse:error:). Your app would remain responsive since the connection is on a background thread. However, you would not be able to update anything until all the data is received.


So I know this is a pretty old question but I ran into the same issue and after hours of going through documentation and blogs I found a great solution in this post from Wim Haanstra http://www.depl0y.com/?p=345

Putting your NSOperation in an infinite loop until you get data back should do the trick!

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜