我使用以下代码在视图控制器中更改名为topPlaces
的属性。行[FlickrFetcher topPlaces]
返回NSArray
,我的属性topPlaces
当然也是NSArray。
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
的值,由于某种原因仍然是NULL。有什么我想念的吗?
答案 0 :(得分:3)
在您当前的方法完成之后,您的ivar将不会被设置。您对[FlickrFetcher topPlaces]
的呼叫与您当前的方法并行运行,需要一段随机时间才能完成。当它完成时,它会回调主线程,这将在运行循环的下一次迭代中执行
这意味着在第二个dispatch_async()
块中,您需要在设置ivar后调用任何方法来显示数据。
答案 1 :(得分: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
,那么当执行到达NSArray *topPlaces = [FlickrFetcher topPlaces];
时,NULL
的值为self.topPlaces = 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 = 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
}