1

各位程序员,

我是否对以下代码做一些根本性的错误,因为它在尝试让主队列初始化 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];
                           }];
4

3 回答 3

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引用以避免保留循环。

希望有帮助!

于 2013-09-20T08:40:42.737 回答
0

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

于 2013-09-20T11:14:02.097 回答
0

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

是的,dispatch_get_main_queue()允许在块内。

于 2013-09-20T08:23:02.177 回答