Ios 当响应NSURLSessionUploadTask完成块中发生的更改而调用时,UI更新*仅*缓慢

Ios 当响应NSURLSessionUploadTask完成块中发生的更改而调用时,UI更新*仅*缓慢,ios,objective-c,delegates,nsurlsession,nsurlsessionuploadtask,Ios,Objective C,Delegates,Nsurlsession,Nsurlsessionuploadtask,该应用程序与我的服务器上的php脚本交互。用户可以创建预订,并将详细信息写入数据库。随后,他们可以取消该预订 在应用程序中,预订是一个对象,负责从服务器收集自己的详细信息。预订也可以自动取消(根据用户的请求)-按BookingViewController中的“取消按钮”调用预订的(void)cancelBooking方法,该方法使用NSURLSessionUploadTask将{“invoiceNumber”:self.invoiceNumber}中的json数据发布到bookings canc

该应用程序与我的服务器上的php脚本交互。用户可以创建预订,并将详细信息写入数据库。随后,他们可以取消该预订

在应用程序中,预订是一个对象,负责从服务器收集自己的详细信息。预订也可以自动取消(根据用户的请求)-按
BookingViewController
中的“取消按钮”调用预订的
(void)cancelBooking
方法,该方法使用NSURLSessionUploadTask将
{“invoiceNumber”:self.invoiceNumber}中的json数据发布到
bookings cancel.php

数据库被更新,uploadSession返回新的详细信息,预订也会根据更新本身。所有这一切都是很好的反应-在不到一秒钟的时间内,一致地向上和向后

当我尝试在
BookingViewController
(交货日期和价格标签)上使用booking对象更新自身后读取的值(在uploadSession完成块内)更新UI时,问题出现了

BookingViewController被指定为预订的代理。预订是为KVO在其自己的“价格”属性上设置的。无论何时价格发生变化,预订都会调用
BookingViewController
上的委托方法
priceDidChange:
,触发
NSLog
并更新到
deliveryLabel.text
priceLabel.text

- (void)priceDidUpdate:(NSString *)updatedPrice {
    NSLog(@"priceDidUpdate delegate notification - updatedPrice is: %@", updatedPrice);
    [self.deliveryLabel setText:@"N/A"];
    [self.priceLabel setText:updatedPrice];
}
测试表明,如果我直接从“取消”按钮更新价格,或者在上传任务之外的
cancelBooking
方法中使用任何其他显式命令(例如,self.price=@“123.45”)更新价格,则UI的更新速度与
NSLog
的写入速度一样快(即,几乎是瞬间)

但是,如果在uploadTask completion块内更新了价格,则NSLog将同样响应,但对
deliveryLabel.text
和priceLabel.text的更新非常缓慢
-延迟大约在5到12秒之间变化

我有
nslog
到处都是,我相信这不仅仅是因为向预订对象或从预订对象获取更新值的延迟。我已经很容易地看到了二十次“
pricediddupdate委托通知”
-updatedPrice是:0.00”(更新后的价格),然后在
self.priceLabel.text
实际设置为
@“0.00”
之前计数到10。完全被难住了

如有必要,可使用
临时会话配置
配置
NSURLSession
,无需调整

根据对
priceDidChange
的调用是否来自uploadTask completion块的内部或外部,是否有任何原因导致
BookingViewController
中的UI更新需要更长的时间


提前谢谢

使用主队列更新UI。使用以下代码:

- (void)priceDidUpdate:(NSString *)updatedPrice 
{
    dispatch_async(dispatch_get_main_queue(), ^()
    {
            //Add method, task you want perform on mainQueue
            //Control UIView, IBOutlet all here
            NSLog(@"priceDidUpdate delegate notification - updatedPrice is: %@", updatedPrice);
            [self.deliveryLabel setText:@"N/A"];
            [self.priceLabel setText:updatedPrice];
    });
}

确保您正在更新主线程上的UI…谢谢,Shai。我已经研究过了,还做了一些GCD教程,但是。。。UI更新总是从priceDidChange内部触发-唯一的区别在于调用priceDidChange的位置:uploadTask完成块内部或外部。我是否错误地认为这应该排除使用哪个线程调用UI更新?无需深入研究您的代码或试图理解您试图做什么,甚至试图找出代码在何处执行-这可以通过将标签更新包装在主队列上运行的调度/同步块中轻松解决…谢谢你,NJ!工作得很有魅力。在我的斗争中,我确实开始钻研GCD,但它太陌生了——答案看起来像是我尝试过的东西,只是它确实有效!:-)FWIW,我是第一次打电话,也是一个长期的听众。所以FTW。再次感谢!