4

我正在尝试使用 3rd 方库下载文件AFNetworking,其核心是NSOperation一个可以设置完成块的对象,用于下载完成时。

不知何故,animateWithDuration:这个块内的一个不能正常运行:它的完成块和实际动画都延迟了大约 5 或 60 秒,或者根本不运行。知道它完全启动的唯一方法是通过 NSLog 调用。

让我演示一下:

[UIView animateWithDuration:0.1
    animations:^{
        controller.view.alpha=0.5;
        NSLog(@"First Try Start");
    }
    completion:^(BOOL finished) {
        NSLog(@"First Try End");
}];


// Here comes the NSOperation completion block
[self->currentConnection setCompletionBlock:^{
        NSLog(@"downloadComplete!");
        [UIView animateWithDuration:0.1
            animations:^{
                controller.view.alpha=0.5; // this doesn't run immediately, only the NSLog line
                NSLog(@"Second Try Start");
    }
    completion:^(BOOL finished) {
                             NSLog(@"Second Try End");
    }];
}];

控制台输出:

2013-06-28 23:22:11.374 ML[7831:c07] First Try Start
2013-06-28 23:22:11.477 ML[7831:c07] First Try End
2013-06-28 23:22:11.742 ML[7831:1303] downloadComplete!
2013-06-28 23:22:11.745 ML[7831:1303] Second Try Start
2013-06-28 23:23:05.007 ML[7831:c07] Second Try End

帮助表示赞赏!

4

2 回答 2

5

UIKit 并不是特别线程安全的。在主线程以外的线程中操作 UIKit 对象会导致不可预知的结果,主要是对象无法明显响应状态变化的形式。

您可以在完成块中使用 GCD 来安排块在主线程上运行:

[self->currentConnection setCompletionBlock:^{
    NSLog(@"downloadComplete!");
    dispatch_queue_t mainQueue = dispatch_get_main_queue();
    dispatch_async(mainQueue, ^{
        [UIView animateWithDuration:0.1
            animations:^{
                    controller.view.alpha=0.5;
                    NSLog(@"Second Try Start");
            }
            completion:^(BOOL finished
                NSLog(@"Second Try End");
            }
        ];
    });
}];
于 2013-06-28T21:41:51.563 回答
0

// 在你的类中定义以下方法

-(void)updateView:(UIView *)paramView {
   paramView = 0.5
}

// 并在您设置 controller.alpha = 0.5 的地方调用以下代码行 // 现在您正在更新主线程上的 alpha

[self performSelectorOnMainThread:@selector(updateView:)  withObject:controller.view waitUntilDone:YES];
于 2013-06-28T21:44:34.760 回答