2013-07-03 4 views
0

Я пытаюсь реорганизовать код NSJSONSerialization так, чтобы он не был в основном потоке. На данный момент приложение немного вяло.Как реорганизовать код так, что его нет в основной теме

Я хотел бы реорганизовать этот код на то, что у меня есть, и возникают проблемы с синтаксисом, особенно с обработкой ошибок. Например, если я возьму мой существующий код (requestData: метод) и поместить его в

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 
}); 

таблица больше не загружает данные.

благодарит за любую помощь.

-(void)requestData { 

    [HUD showUIBlockingIndicatorWithText:@"Fetching JSON"]; 

    NSError *requestError = nil; 

    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL 
                  URLWithString:kURL]]; 

    NSData *response = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:&requestError]; 

    NSError *jsonParsingError = nil; 

    if (requestError) 
    { 
     NSLog(@"sync. request failed with error: %@", requestError); 
    } 
    else 
    { 
     // handle data 
     publicData = [NSJSONSerialization JSONObjectWithData:response 
                    options:0 
                     error:&jsonParsingError]; 
     publicDataArray = [publicData objectForKey:@"data"]; 

    } 

    /* 
    for(publicDataDict in publicDataArray) { 
    NSLog(@"data output is %@",[publicDataDict objectForKey:@"title"]); 

    } 
    */ 
    [self.mainTableView reloadData]; 

    [HUD hideUIBlockingIndicator]; 
} 

Вот код, который я бы хотел использовать.

-(void)viewDidAppear:(BOOL)animated 
{ 

    [HUD showUIBlockingIndicatorWithText:@"Fetching Data"]; 

    //1 
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 
     //code executed in the background 
     //2 
     NSData* ghData = [NSData dataWithContentsOfURL: 
          [NSURL URLWithString:kURL] 
          ]; 
     //3 
     NSDictionary* json = nil; 
     if (ghData) { 
      json = [NSJSONSerialization 
        JSONObjectWithData:ghData 
        options:kNilOptions 
        error:nil]; 
     } 

     //4 
     dispatch_async(dispatch_get_main_queue(), ^{ 
      //code executed on the main queue 
      //5 


      [self.tableView reloadData]; 
      [HUD hideUIBlockingIndicator]; 
     }); 

    }); 
} 
+0

Пожалуйста, укажите конкретные проблемы, включая журналы компилятора/исключения и трассировки стека. Не заставляйте нас догадываться о том, с чем у вас проблемы. – Wain

+0

@Wain Я сделал редактирование. В основном, когда я помещаю код в dispatch_async (dispatch_get_global_queue (DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),^{ }); данные таблицы больше не загружаются – hanumanDev

+0

Правильно ли разбирается json, или вы получаете сообщение об ошибке. Отладка для проверки. – Wain

ответ

1

Таким образом, возможная догадка wold будет для этого, вероятно, метод перезагрузки таблицы будет называться раньше. поэтому в последнем случае вы можете перезагрузить таблицу, как показано ниже.

-(void)viewDidAppear:(BOOL)animated 
{ 

    [HUD showUIBlockingIndicatorWithText:@"Fetching Data"]; 

    //1 
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 
     //code executed in the background 
     //2 
     NSData* ghData = [NSData dataWithContentsOfURL: 
          [NSURL URLWithString:kURL] 
          ]; 
     //3 
     NSDictionary* json = nil; 
     if (ghData) { 
      json = [NSJSONSerialization 
        JSONObjectWithData:ghData 
        options:kNilOptions 
        error:nil]; 
     } 

     //4 
     [self performSelectorOnMainThread:@selector(reloadTable) withObject:nil waitUntilDone:NO]; 

    }); 
} 

и после этого сделайте подобный.

-(void)reloadTable { 

    [self.tableView reloadData]; 
    [HUD hideUIBlockingIndicator]; 
} 

Также проверьте, если методы TableView DataSource делегата вызывался, если он не вызывался затем установить делегат UITableView.

-3

Попробуйте первое место в рефакторинга преобразовать проект для новой архитектуры АРК, я этот пост в старом ответ, посмотрите здесь:

My Post

Надежда это поможет вам или дать представление для рефакторинга кода;)

+0

ОК, спасибо. Я проверю это. – hanumanDev

0

Если вы переформатируете свой код, воспользуйтесь функциями. Вы должны написать логику/код, предназначенные для выполнения определенной задачи в отдельной функции, а также ваш LOC в любой функции не должен превышать более 20, в обычных случаях.

Говоря о вашей проблеме, похоже, вы правильно это применили, но я не вижу, как вы определяете источник tableView, проверьте, не превратили ли вы JSON в какой-либо контейнерный объект, а именно из словаря или массива.

-(void)viewDidAppear:(BOOL)animated 
{ 
    [HUD showUIBlockingIndicatorWithText:@"Fetching Data"]; 

    [self fetchData]; 
} 

-(void)fetchData 
{ 
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 
    // switch to a background thread and perform your expensive operation 

    NSData* ghData = [NSData dataWithContentsOfURL: 
          [NSURL URLWithString:kURL] 
          ]; 

    NSDictionary* json = nil; 

    if (ghData) 
    { 
    json = [NSJSONSerialization 
        JSONObjectWithData:ghData 
        options:kNilOptions 
        error:nil]; 
    } 

    dispatch_async(dispatch_get_main_queue(), ^{ 
    // switch back to the main thread to update your UI 
    [self.tableView reloadData]; 
    [HUD hideUIBlockingIndicator]; 
    }); 

}); 
} 
2

Многие люди предполагают, что отправка процесса на задний план автоматически избавит их от применения любой медлительности, это НЕПРАВИЛЬНОЕ предположение. Если вы отправляете интенсивную задачу с процессором на задний план, он также блокирует процессор. Чтобы многопоточность работала в вашу пользу, вы должны быть методичными.

Теперь на вашу проблему, самое простое решение для вас, чтобы использовать то, что Apple уже предоставляет, NSURLConnection - ваш лучший выбор, НИКОГДА НЕ используйте [NSData dataWithContentsOfURL:], это определенно нет. Это не проблема NSJSONSerialization, это сетевой запрос.

У вас есть два варианта.

1) Используйте NSRULConnection метод делегата и место ваши методы JSON сериализации в - connectionDidFinishLoading: метод делегата

2) Используйте методы блок для NSURLConnection [NSURLConnection sendAsynchronousRequest: очереди: completionHandler:] (Мой предпочтительный выбор)

-(void)viewDidAppear:(BOOL)animated 
{ 
    [HUD showUIBlockingIndicatorWithText:@"Fetching Data"]; 

    NSURLRequest *request = [NSURLRequest requestWithURL:URL]; 
    [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) { 

    if (!error) { 
     NSError *jsonError = nil; 
     NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&jsonError]; 

     if (jsonError) { 
      NSLog(@"Error parsing JSON"); 
      //Optionally display error message here 
     }else{ 

      self.globalDictionary = jsonDict; 

      [self.tableView reloadData]; 
      [HUD hideUIBlockingIndicator]; 
     } 

    }else 
    { 
     NSLog(@"Error with request"); 

     [HUD hideUIBlockingIndicator]; 
     //Optionally display error message here 
    } 


}]; 

}

Примечание: globalDictionary является NSDictionary экземпляра, который заполняет таблицу.

Смежные вопросы