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
- NSURLConnection supports asynchronous connections by itself with a delegate. You should use this. If you have specific issue(s), you should describe those.
- Check out the ASIHTTPRequest library.
- 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!
精彩评论