2013-05-21 135 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 
}