我想我陷入僵局但不太明白为什么

时间:2013-09-08 23:06:21

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

我正在尝试使用GCD一个接一个地放置图像,如下所示

-(void)setUpImages {
    NSArray *images  =   @[[UIImage imageNamed:@"blogger-icon.png"],
                           [UIImage imageNamed:@"gplus-icon.png"],
                            [UIImage imageNamed:@"facebok-icon.png"]
                           ];
    [images enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
          dispatch_sync(dispatch_get_main_queue(), ^{
                UIImageView     *imageView  =   [[UIImageView alloc] initWithFrame:CGRectMake(80, idx * ((UIImage*)obj).size.height + idx*30 + 10, ((UIImage*)obj).size.width, ((UIImage*)obj).size.height)];
                NSLog(@"index is %@",NSStringFromCGRect(imageView.frame));

                [imageView setImage:(UIImage*)obj];
                [self.view.layer addSublayer:imageView.layer];
                sleep(1); 
            });
    }];

}

我正在使用dispatch_sync因为我希望它会一直等到它的块完成(第一张图像放在屏幕上)然后第二张图像就会出现,所以第三张图像就是这样。现在所有的事情都发生在主线上。

然而,似乎我在中间遇到了僵局,我的逻辑在某些方面是错误的。

我需要帮助来了解这种情况。请帮忙。

3 个答案:

答案 0 :(得分:6)

来自dispatch_sync的文档:

  

调用此函数并以当前队列为目标会导致死锁。


那就是说,我认为你有一个设计问题,你可以在不涉及GCD的情况下达到预期的效果。

由于您希望每隔 k 秒更新UI,因此请避免使用sleep(1)并使用performSelector:withObject:afterDelay:以递归方式调用方法。

这样的东西
- (void)updateImageViewWithImageAtIndex:(NSNumber *)i {
    UIImage * image = self.images[i.intValue];
    UIImageView * imageView = [[UIImageView alloc] initWithFrame:CGRectMake(80, idx * image.size.height + idx*30 + 10, image.size.width, image.size.height)];
    NSLog(@"index is %@",NSStringFromCGRect(imageView.frame));
    [imageView setImage:image];
    [self.view.layer addSublayer:imageView.layer];

    if (i < images.count - 1) {
        [self performSelector:@selector(updateImageViewWithImageAtIndex:) withObject:@(i.intValue++) afterDelay:1];
    }
}

- (void)setUpImages {
    // Assuming you have declared images as a property
    self.images = @[[UIImage imageNamed:@"blogger-icon.png"],
                        [UIImage imageNamed:@"gplus-icon.png"],
                        [UIImage imageNamed:@"facebok-icon.png"]
                       ];
    [self updateImageViewFromImages:images index:0];
}

答案 1 :(得分:2)

现在我可能完全错了,但看起来你要做的就是每秒更换一次图像视图中的图像,在这种情况下你的方法是不正确的。 UIImageView具有内置的方法。例如:

NSArray *images  =   @[[UIImage imageNamed:@"blogger-icon.png"],
                       [UIImage imageNamed:@"gplus-icon.png"],
                       [UIImage imageNamed:@"facebok-icon.png"]
                       ];

UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(80, idx * ((UIImage*)obj).size.height + idx*30 + 10, ((UIImage*)obj).size.width, ((UIImage*)obj).size.height)];
[imageView setAnimationDuration:3];
[imageView setAnimationImages:images];
[imageView startAnimating];

答案 2 :(得分:0)

我认为加布里埃尔钉住了上面的僵局。不要调用dispatch_sync并传入主队列。

另一个可能的问题:我怀疑操纵图层的视图不是线程安全的。它不应该导致死锁,但它可能会导致不良后果。