# Binder

**Binder** 主要有以下两个特征：

* 不会处理错误事件
* 确保绑定都是在给定 [Scheduler](https://3440217568.gitbook.io/rxswift/rxswift_core/schedulers) 上执行（默认 **MainScheduler**）

一旦产生错误事件，在调试环境下将执行 `fatalError`，在发布环境下将打印错误信息。

## 示例

在介绍 [AnyObserver](https://3440217568.gitbook.io/rxswift/rxswift_core/observer/any_observer) 时，我们举了这样一个例子：

```swift
let observer: AnyObserver<Bool> = AnyObserver { [weak self] (event) in
    switch event {
    case .next(let isHidden):
        self?.usernameValidOutlet.isHidden = isHidden
    default:
        break
    }
}

usernameValid
    .bind(to: observer)
    .disposed(by: disposeBag)
```

由于这个观察者是一个 **UI 观察者**，所以它在响应事件时，只会处理 `next` 事件，并且更新 **UI** 的操作需要在主线程上执行。

因此一个更好的方案就是使用 **Binder**：

```swift
let observer: Binder<Bool> = Binder(usernameValidOutlet) { (view, isHidden) in
    view.isHidden = isHidden
}

usernameValid
    .bind(to: observer)
    .disposed(by: disposeBag)
```

**Binder** 可以只处理 `next` 事件，并且保证响应 `next` 事件的代码一定会在给定 [Scheduler](https://3440217568.gitbook.io/rxswift/rxswift_core/schedulers) 上执行，这里采用默认的 **MainScheduler**。

## 复用

由于**页面是否隐藏**是一个常用的观察者，所以应该让所有的 `UIView` 都提供这种观察者：

```swift
extension Reactive where Base: UIView {
  public var isHidden: Binder<Bool> {
      return Binder(self.base) { view, hidden in
          view.isHidden = hidden
      }
  }
}
```

```swift
usernameValid
    .bind(to: usernameValidOutlet.rx.isHidden)
    .disposed(by: disposeBag)
```

这样你不必为每个 **UI** 控件单独创建该观察者。这就是 `usernameValidOutlet.rx.isHidden` 的由来，许多 **UI 观察者** 都是这样创建的：

* **按钮是否可点击 `button.rx.isEnabled`：**

  ```swift
  extension Reactive where Base: UIControl {
    public var isEnabled: Binder<Bool> {
        return Binder(self.base) { control, value in
            control.isEnabled = value
        }
    }
  }
  ```
* **`label` 的当前文本 `label.rx.text`：**

  ```swift
  extension Reactive where Base: UILabel {
    public var text: Binder<String?> {
        return Binder(self.base) { label, text in
            label.text = text
        }
    }
  }
  ```

你也可以用这种方式来创建自定义的 **UI 观察者**。


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://3440217568.gitbook.io/rxswift/rxswift_core/observer/binder.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
