ios - 强制所有 UIKit 的东西在主线程中完成

标签 ios objective-c grand-central-dispatch dispatch-async

我正在做一个复杂的应用程序,它必须在很多线程上执行操作并经常更新界面。

所以我要补充很多

  dispatch_async(dispatch_get_main_queue(), ^{

  });

在将 UI 更新分派(dispatch)到主线程的代码中间,我发现它非常丑陋且具有破坏性。

所以,我有创建元素子类的想法,例如 UILabelUITextField 等,覆盖它们的主线程方法,如下所示:

- (void)setAttributedText:(NSAttributedString *)attributedText {
  dispatch_async(dispatch_get_main_queue(), ^{
    [super setAttributedText:attributedText];
  });
}

- (void)setText:(NSString *)text {
  dispatch_async(dispatch_get_main_queue(), ^{
    [super setText:text];
  });
}

- (void)scrollRangeToVisible:(NSRange)range {
  dispatch_async(dispatch_get_main_queue(), ^{
    [super scrollRangeToVisible:range];
  });
}

但同样,我必须将相同的代码分散到所有这些类中。

有没有更好的办法?

最佳答案

我认为您的问题出现是因为您将计算与 UI 紧密耦合。您可以查看替代架构,例如 MVVM ,虽然正式采用此架构在您拥有绑定(bind)框架时效果最好。

即使没有绑定(bind)框架,您也可以通过引入一些模型属性和一些 setter/getter 代码来改善您的情况,以处理实际的 UI 元素。

例如声明一对属性,一个用于文本域,一个用于文本

@property (weak, nonatomic)  UITextField *someTextField;
@property (strong, nonatomic) NSString *someText;

现在,实现 setter 和 getter 方法来耦合它们:

-(NSString *)someText {
   return self.someTextField.text;
} 

-(Void *)setSomeText: (NSString *)newValue {
    dispatch_async(dispatch_get_main_queue(), ^{
        self.someTextField.text = newValue
  });
}

现在,这是一个非常简单的示例,并且有一个小问题,即在设置 someText 后立即检索它的值不会返回原来的值只是由于设置操作的异步性质而设置,但在大多数情况下这不应该成为问题。它确实演示了如何开始将数据模型与 UI 元素分离,从而将对数据的关注与对更新 UI 元素的机制的关注分开。

关于ios - 强制所有 UIKit 的东西在主线程中完成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47499954/

相关文章:

ios - 在 iOS 上通过(外部)javascript 启动 YouTube iframe 播放器

ios - 如何将 UIGestureRecognizerDelegate 分配给 CKComponentController

iphone - SIGTRAP -[__NSCFString 计数] : unrecognized selector sent to instance

ios - 搜索栏背景颜色灰色 ios7

ios - 获取在 iOS 上的来电中显示的联系人图像

iphone - 在启动图像上隐藏状态栏

ios - 如何在 Firebase observeEvent block iOS 中更新 UI

ios - 捕获的 self 在 dispatch_async 中被释放

ios - AVCaptureSession 和相机线程未关闭 [iOS]

ios - 谷歌分析选择退出 "how to"