2014-01-28 41 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_Arraystudent_temp。顯然,這條線是沒有意義的,因爲你正在異步填充student_temp。如果您試圖同時訪問兩個隊列中的保存變量,那麼您將面臨同步問題。不要在viewDidLoad的末尾分配student_Arraystudent_temp,而只是在嵌套的dispatch_async調用中進行。

  2. 塊內,您正在填充和設置student_temp。將該變量作用在該塊內可能更有意義,避免了從該塊外部訪問該變量的誘惑,並簡化了代碼,因爲不再需要__block限定符。

  3. 此塊異步運行,因此當您在主隊列中更新student_Array時,可能需要同時更新UI(例如,重新加載tableview或其他)。也許你已經這麼做了,只是爲了簡潔而刪除它,但我只是想確定一下。

這樣:

- (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被保留在塊中,並通過它引用該屬性。

當然,您需要了解併發性問題,例如如果您還需要從主線程訪問數據。對於這一點,你可能還是想在你的異步GCD塊的末尾有這樣:

// done populating the data 
dispatch_async(dispatch_get_main_queue(), ^{ 
    // update the UI 
} 
相關問題