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

时间:2017-11-26 19:09:00

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

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

所以我必须添加很多

  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];
  });
}

但同样,我必须在这些类中分配相同的代码。

有更好的方法吗?

1 个答案:

答案 0 :(得分:1)

我认为您的问题正在发生,因为您将计算与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的值赢回返回刚才的值由于设置操作的异步性质而设置,但在大多数情况下这不应该成为问题。它确实演示了如何开始将数据模型与UI元素分离,从而将数据的关注点与更新UI元素的机制相关联。