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

Forcing all UIKit stuff to be done in the main thread

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

所以我要补充很多

  dispatch_async(dispatch_get_main_queue(), ^{

  });

在向主线程分派 UI 更新的代码中间,我发现它丑陋且具有破坏性。

所以,我想创建子类 元素,如 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,尽管当您拥有绑定框架时正式采用此架构效果最佳。

即使没有绑定框架,您也可以通过引入一些模型属性和一些 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 的值 不会 return 由于设置操作的异步性质而刚刚设置的值,但在大多数情况下这不应该成为问题。它确实演示了如何开始将数据模型与 UI 元素分离,从而将对数据的关注与对更新 UI 元素的机制的关注分开。