2014-01-28 2 views
0

Я новичок. Я использую Grand Central Dispatch для заполнения массива (student_temp) в другом потоке. Эта часть работает нормально. Проблема в том, что я не могу передать массив в свойство класса (student_Array), где он используется во всем классе. Я не могу вернуть массив в основной поток.Как получить массив из Grand Central Dispatch?

он отлично работает, пока не вернусь к основной теме, и я не могу передать student_temp в student_Array (свойство) внутри или вне GCD.

Что я делаю неправильно, или лучше заполнить свойство массива с помощью GCD?

Благодарим за помощь. И, пожалуйста, попробуйте объяснить на нетехническом языке, если возможно, я новичок в этом.

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

    R2LFetcher *studentFetch = [[R2LFetcher alloc] init]; 
    __block NSMutableArray *student_temp = [[NSMutableArray alloc] init]; 

    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul); 
    dispatch_async(queue, ^{ 

     //long-running code goes here… 
      student_temp = [studentFetch fetchToStudentArray]; 

     dispatch_async(dispatch_get_main_queue(), ^{ 

      // code the updates the main thread (UI) here... 
      student_Array = student_temp; 

     }); 

    }); 
    student_Array = student_temp; 
+0

что student_Array – codercat

ответ

0

Пару реакций:

  1. В последней строке кода, вы устанавливаете student_Array - student_temp. Ясно, что эта строка не имеет смысла, потому что вы заселяете student_temp асинхронно. И вы открываете проблемы синхронизации, если пытаетесь одновременно получить доступ к переменной сохранения в двух очередях. Не утруждайте назначением student_Arraystudent_temp в конце viewDidLoad, а просто делайте это внутри вложенных вызовов dispatch_async.

  2. Внутри блока вы заселяете и устанавливаете student_temp. Вероятно, имеет смысл сделать эту переменную областью внутри этого блока, избегая соблазна доступа к нему из-за пределов этого блока, а также упрощая ваш код, потому что квалификатор __block больше не нужен.

  3. Этот блок работает асинхронно, поэтому при обновлении student_Array в основной очереди вы можете обновить свой интерфейс одновременно (например, перезагрузить табличный просмотр или что-то еще). Возможно, вы делаете это уже и просто удалили его ради краткости, но я просто хотел убедиться.

Таким образом:

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0ul); 
    dispatch_async(queue, ^{ 

     R2LFetcher *studentFetch = [[R2LFetcher alloc] init]; 

     // long-running code goes here, for example ... 

     NSMutableArray *student_temp = [studentFetch fetchToStudentArray]; 

     dispatch_async(dispatch_get_main_queue(), ^{ 

      student_Array = student_temp; 

      // code the updates the main thread (UI) here, for example... 

      [self.tableView reloadData]; 
     }); 
    }); 
} 
+0

Это сработало! большое спасибо!! Я потратил на это несколько дней. Итак, я думаю, reloadData просто говорит программе возобновить работу над основным потоком? Я думал, что мне нужно отправить его на старый основной поток, но я думаю, что главное просто перезагружается отсюда. Во всяком случае, он работает. Еще раз спасибо! Стивен. – user3241993

+0

@ user3241993 Это не значит, что он должен «возобновить работу над основной нитью». Основная нить не прекращалась. Просто, когда представление было загружено, вызывается метод 'viewDidLoad', а затем методы' UITableViewDataSource'.Но этот блок кода «получить данные», который вы написали, выполняется асинхронно, что означает, что он, скорее всего, завершится после того, как будут выполнены методы 'UITableViewDataSource', и в представлении таблицы нет способа узнать, что ему необходимо перезагрузить свои данные, скажите ему это сделать. – Rob

0

Вы должны иметь возможность добавлять объекты в student_Array непосредственно из вашего блока. В отличие от переменных стека, свойства и ivars не копируются при использовании внутри блока. Вместо этого в блоке сохраняется self, и на это свойство ссылается.

Конечно, вам нужно знать о проблемах с параллелизмом, например. если вам нужно также получить доступ к данным из основного потока. Для этого, вы, вероятно, все еще хотите иметь это в конце вашего асинхронном НОД блока:

// done populating the data 
dispatch_async(dispatch_get_main_queue(), ^{ 
    // update the UI 
} 
Смежные вопросы