NSOperation для рисования пользовательского интерфейса при разборе данных? - PullRequest
1 голос
/ 22 января 2010

Надеюсь, вы, ребята, можете мне помочь:)

В основном потоке я создаю NSOperation и добавляю его в очередь. Эта операция выполняет подключение к серверу данных с NSURLConnection, сохраняет полученные данные и анализирует их.

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, которые я отправляю в основной поток для их рисования во время прибытия. (Я создаю UITableView, если прибывает itemTable, или я создаю UIWebView, если прибывает itemWeb)

Использование этого для отправки элемента в основной поток:

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. Я думал, что NSOpertion, будучи другим потоком, не будет блокировать основной поток, но считаю, что именно это и происходит.

Несколько советов по этому вопросу?

Большое спасибо за чтение!

Ответы [ 2 ]

0 голосов
/ 19 октября 2011

Итак, я знаю, что это довольно старый вопрос, но я столкнулся с той же проблемой, и после нескольких часов просмотра документации и блогов в этом сообщении я нашел отличное решение от Wim Haanstra http://www.depl0y.com/?p=345

Помещение вашей NSOperation в бесконечный цикл, пока вы не вернете данные, должно помочь!

0 голосов
/ 22 января 2010

Вы используете NSOperationQueue?

Извлеките этот ответ на вопрос NSOperation блокирует рисование пользовательского интерфейса? для простого примера того, как обновить пользовательский интерфейс с уведомлением от NSOperation, работающего асинхронно в другом потоке. 1008 *

ОБНОВЛЕНИЕ

  1. NSURLConnection самостоятельно поддерживает асинхронные соединения с делегатом. Вы должны использовать это. Если у вас есть конкретные проблемы, вы должны описать их.
  2. Ознакомьтесь с библиотекой ASIHTTPRequest .
  3. Если вы действительно хотите использовать этот подход, вы можете попробовать запустить NSURLConnection синхронно (используя метод класса sendSynchronousRequest: returningResponse: error: ). Ваше приложение останется отзывчивым, так как соединение находится в фоновом потоке. Однако вы не сможете ничего обновить, пока все данные не будут получены.
...