使用GCD线程确保FOR循环的运行顺序? iOS版

时间:2013-04-11 19:01:31

标签: ios objective-c multithreading queue grand-central-dispatch

我有一个串行队列,其中包含两个加载和图像的方法,然后,一旦完成,将图像添加到子视图。图像在NSMutableArray中,所以我在For循环上迭代以加载它们,如下所示:

dispatch_queue_t queue = dispatch_queue_create("com.example.MyQueue", NULL); 
for (int i =0; i<=[pictureThumbnailArray count]-1; i++) {
    dispatch_async(queue, ^{

    NSLog(@"Thumbnail count is %d", [pictureThumbnailArray count]);

        finishedImage = [self setImage:[pictureThumbnailArray objectAtIndex:i]:i];

        if (finishedImage !=nil) {
        dispatch_async(dispatch_get_main_queue(), ^ {
        [self.view addSubview:finishedImage];
    });

        }
    });
                   }

问题是图像似乎是随机加载的。我想要实现的是For循环的每次迭代在下一次迭代开始之前运行并完成 - 这样每次都应该以相同的方式加载图像。

任何人都可以建议实现这一目标的最佳方法 - 我想我可能需要同步setImage方法(队列中的第一个方法)?

更改为:

for (int i =0; i<=[pictureThumbnailArray count]-1; i++) {

    NSLog(@"Thumbnail count is %d", [pictureThumbnailArray count]);

        finishedImage = [self setImage:[pictureThumbnailArray objectAtIndex:i]:i];

        if (finishedImage !=nil) {
        dispatch_async(dispatch_get_main_queue(), ^ {
        [self.view addSubview:finishedImage];
    });

        }
                   }
    });

2 个答案:

答案 0 :(得分:0)

您还有其他一些问题 - 也许您的图像数组不符合您的预期。 queue和mainQueue都是串行队列。为了验证这一点,我只是进行了快速测试并按预期顺序获取了日志消息。我建议您尝试添加日志消息,以便找出订单不符合您预期的原因:

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.

static dispatch_queue_t queue;
    queue = dispatch_queue_create("com.example.MyQueue", NULL);

    for (int i =0; i<=20; i++) {
        dispatch_async(queue, ^{
            dispatch_async(dispatch_get_main_queue(), ^ {
                NSLog(@"Image %d", i);
            });
        } );
    }
}

答案 1 :(得分:0)

如果我们在没有GCD的情况下做更简单的事情怎么办?我建议摆脱它并使用NSURLConnectionDelegate方法。

此方法下载下一张图片:

-(void)startDownload
{
    if (index < URLs.count)
    {
        NSURL *URL = [NSURL URLWithString:URLs[index]];
        _connection = [[NSURLConnection alloc] initWithRequest:[NSURLRequest requestWithURL:URL] delegate:self];
    }
}

connectionDidFinishLoading:委托方法将图像放置到视图中并开始下一次下载。

- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
    UIImage *image = [UIImage imageWithData:_data];
    _data = nil;
    _connection = nil;
    UIImageView *imageView = (UIImageView *)[self.view viewWithTag:100+index];
    imageView.image = image;
    index++;
    [self startDownload];
}

以下是完整的示例:https://github.com/obrizan/TestImageDownload图片相当大,所以请花点时间加载它们。