在块内时是否允许GCD的dispatch_get_main_queue?

时间:2013-09-20 08:14:12

标签: ios grand-central-dispatch restkit-0.20 mbprogresshud

研究员,

我是否在使用下面的代码做了一些根本性的错误,因为它在尝试获取主队列以初始化UIImageView时不起作用?是否允许在一个街区内?我是否需要担心获取主队列或者我是否应该直接在块中初始化UIImageView?如果我将HUD.customView设置为nil它可以正常工作。我正在使用RestKit发出请求并在进行调用时显示MDProgressHUD。

[objectManager.HTTPClient postPath:@"/items/create"
                        parameters:parameters
                           success:^(AFHTTPRequestOperation *operation, id responseObject){
                               NSLog(@"Success!");

                               __block UIImageView *imageView;
                               dispatch_sync(dispatch_get_main_queue(), ^{
                                   UIImage *image = [UIImage imageNamed:@"37x-Checkmark.png"];
                                   imageView = [[UIImageView alloc] initWithImage:image];
                               });

                               self.HUD.customView = imageView;
                               self.HUD.mode = MBProgressHUDModeCustomView;
                               self.HUD.labelText = @"Success";

                               [self.HUD hide:YES afterDelay:1.5];
                           }
                           failure:^(AFHTTPRequestOperation *operation, NSError *error){
                               NSLog(@"Error: %@", [error localizedDescription]);
                               [self.HUD hide:YES afterDelay:2.0];
                           }];

3 个答案:

答案 0 :(得分:1)

UIKit不是线程安全的。与UIKit相关的任何内容和所有内容都需要在主线程上完成。对其他线程上的UIKit元素执行操作将产生不可预测的结果,这正是这里的情况。

您需要在主线程中使用HUD相关代码。 HUD也是UIKit元素。

__weak YourClass *weakSelf = self;
dispatch_sync(dispatch_get_main_queue(), ^{
    UIImage *image = [UIImage imageNamed:@"37x-Checkmark.png"];
    imageView = [[UIImageView alloc] initWithImage:image];

    //Modify the HUD
    weakSelf.HUD.customView = imageView;
    weakSelf.HUD.mode = MBProgressHUDModeCustomView;
    weakSelf.HUD.labelText = @"Success";
    [weakSelf.HUD hide:YES afterDelay:1.5];
});

一种预防措施,在块中使用self时,您需要创建并使用weak引用以避免保留周期。

希望有所帮助!

答案 1 :(得分:0)

主线程中不需要init UI对象。但是所有使用UI的操作都必须在主线程中执行。 因此,如果您想创建一些子视图或想要获取某些数据,可以在后台进行。但是当你想在控制器的视图中添加它或想要重新加载视图时,你必须在主线程中进行。

是的,块内允许dispatch_get_main_queue()

答案 2 :(得分:0)

主线程上已调用successfailure块(您可以添加日志以检查是否存在这种情况),这是由RestKit为您完成的。因此,当您调用dispatch_sync时,您可能会阻止主线程等待自己。所以,通常你应该使用dispatch_async,但在这种情况下你应该删除这个尝试过的线程切换。