0

我正在使用以下代码来更改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。有什么我想念的吗?

4

2 回答 2

3

在当前方法完成之前,不会设置您的 ivar。您的调用[FlickrFetcher topPlaces]与您当前的方法并行运行,并且需要随机的时间才能完成。完成后,它会回调主线程,主线程会在运行循环的下一次迭代中执行

这意味着在您的第二个dispatch_async()块中,您需要在设置 ivar 后调用任何方法来显示数据。

于 2013-05-21T01:38:48.637 回答
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];是。NULLself.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因为它不会被设置,直到 after[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
}
于 2013-05-21T01:45:33.117 回答