ios - 在 block 内是否允许 GCD 的 dispatch_get_main_queue?

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

各位程序员,

我是否对以下代码做了一些根本性的错误,因为它在尝试让主队列初始化 UIImageView 时不起作用?这在一个 block 内允许吗?我是否需要担心获得主队列或者我应该直接在 block 内初始化 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];
                           }];

最佳答案

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];
});

一个预防措施,当在 block 中使用 self 时,您需要创建并使用 weak 引用以避免保留循环。

希望对您有所帮助!

关于ios - 在 block 内是否允许 GCD 的 dispatch_get_main_queue?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18911890/

相关文章:

javascript - 区分应用程序访问的 Wifi 连接

ios - 减少启动图像时间 IOS

ios - RestKit 映射嵌套属性失败

ios - 将 RestKit 从 0.10 升级到 0.20 的问题

objective-c - RestKit 0.20 — 核心数据 : error: Failed to call designated initializer on NSManagedObject class

ios - UITableView 滑动操作删除和编辑自定义 View

cocoa - 如何使用 GCD 安全地锁定变量?

objective-c - NSURLConnection 与 NSData + GCD

ios - GCD dispatch_after 调用导致 SIGBUS 信号

iphone - 离开初始 View Controller 时停止播放音乐(使用 AVAudioPlayer)