2013-05-21 166 views
0

我正在使用以下代碼更改視圖控制器內名爲topPlaces的屬性。行[FlickrFetcher topPlaces]返回NSArray和我的財產topPlaces,當然,也是一個NSArray。在dispatch_async中設置屬性,但塊完成後屬性爲NULL

dispatch_queue_t downloadQueue = dispatch_queue_create("flickr topPlace", NULL); 
dispatch_async(downloadQueue, ^{ 
    NSArray *topPlaces = [FlickrFetcher topPlaces]; 
    dispatch_async(dispatch_get_main_queue(), ^{ 
     self.topPlaces = topPlaces; 
    }); 
}); 
dispatch_release(downloadQueue); 

然而,該塊執行完畢,如果我登錄的self.topPlaces值後,這仍然是空的某些原因。有什麼我失蹤?

+0

您究竟在哪裏檢查自我.topPlaces? – BergQuester

+0

這段代碼被放到viewDidLoad中,我是'NSLog',它也在viewDidLoad上面的代碼之後。此外,如果它不是NULL,我的視圖會顯示一些內容,但目前它沒有顯示任何內容。 – Enzo

+0

ut是異步代碼在FlickrFetcher代碼運行之前的調度之後運行的'NSLOg'ing。 – zaph

回答

3

您的伊娃不會被設置,直到您的當前方法完成後。您撥打[FlickrFetcher topPlaces]的電話與您當前的方法並行運行,並需要一段隨機時間才能完成。當它完成時,它會回調到主線程,該線程在運行循環的下一次迭代中執行

這意味着在您的第二個dispatch_async()塊中,需要調用任何方法以在設置後顯示數據伊娃。

+0

我明白了。現在它已經修復了。數據加載後,我也沒有刷新我的視圖。感謝您指出了這一點。 – Enzo

+2

這個答案的第一部分是不正確的,在'dispatch_async()'之後立即釋放'downloadQueue'是完全安全的,隊列只會在隊列完成後被銷燬。 – das

+0

das-檢查後,我發現你是正確的。我編輯了我的答案。謝謝。 – BergQuester

2

請先嚐試存根self.topPlaces這樣的:

dispatch_queue_t downloadQueue = dispatch_queue_create("flickr topPlace", NULL); 
dispatch_async(downloadQueue, ^{ 
    NSArray *topPlaces = [FlickrFetcher topPlaces]; 
    dispatch_async(dispatch_get_main_queue(), ^{ 
     self.topPlaces = @[@"test", @"test2", @"test3"]; 
    }); 
}); 

然後檢查self.topPlaces值。如果它仍然是NULL那麼我需要問你的財產self.topPlaces有什麼終身限定符(例如強,弱,轉讓)?如果它是weak那麼當然topPlaces的值將是NULL,因爲不會有任何強的指針指向它。如果是strong,則當執行到達self.topPlaces = topPlaces;時,NSArray *topPlaces = [FlickrFetcher topPlaces];的值爲NULL

要考慮的另一件事是,當您執行異步操作時,主線程上的執行將繼續執行。所以,如果你正在做以下...

dispatch_queue_t downloadQueue = dispatch_queue_create("flickr topPlace", NULL); 
dispatch_async(downloadQueue, ^{ 
    NSArray *topPlaces = [FlickrFetcher topPlaces]; 
    dispatch_async(dispatch_get_main_queue(), ^{ 
     self.topPlaces = topPlaces; 
    }); 
}); 
NSLog(@"topPlaces = %@", self.topPlaces); 

然後我希望self.topPlaces永遠是NULL當它擊中NSLog由於它不會被設置到後[FlickrFetcher topPlaces]已經完成並返回與執行繼續進入dispatch_async(dispatch_get_main_queue()...。此時應該設置值。您可能需要執行以下操作,以確保您不僅設置屬性,還會在異步操作完成後執行某種更新操作以更新UI ...

dispatch_queue_t downloadQueue = dispatch_queue_create("flickr topPlace", NULL); 
dispatch_async(downloadQueue, ^{ 
    NSArray *topPlaces = [FlickrFetcher topPlaces]; 
    dispatch_async(dispatch_get_main_queue(), ^{ 
     [self updateUIWithTopPlaces:topPlaces]; 
    }); 
}); 

- (void)updateUIWithTopPlaces:(NSArray*)topPlaces { 
    self.topPlaces = topPlaces; 
    // Perform your UI updates here 
}