Skip to content

Commit

Permalink
Remove NSObject conformance to BindingExecutionContextProvider.
Browse files Browse the repository at this point in the history
  • Loading branch information
srdanrasic committed Mar 27, 2017
1 parent 6ce6773 commit c5eaa28
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 37 deletions.
50 changes: 26 additions & 24 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -751,51 +751,53 @@ public protocol Deallocatable: class {

ReactiveKit provides conformance to this protocol for `NSObject` and its subclasses out of the box.

Protocol `BindingExecutionContextProvider` provides the execution context on which the object can be updated. Execution context is just a wrapper over dispatch queue or a thread. You can see how it is implemented [here](https://github.com/ReactiveKit/ReactiveKit/blob/master/Sources/ExecutionContext.swift).
How do you conform to `Deallocatable`? The simplest way is conforming to `DisposeBagProvider` instead.

```swift
public protocol BindingExecutionContextProvider {
/// A type that provides a dispose bag.
/// `DisposeBagProvider` conforms to `Deallocatable` out of the box.
public protocol DisposeBagProvider: Deallocatable {

/// An execution context used to deliver binding events.
var bindingExecutionContext: ExecutionContext { get }
/// A `DisposeBag` that can be used to dispose observations and bindings.
var bag: DisposeBag { get }
}
```

`NSObject` conforms to this protocol by providing `.immediateOnMain` context.

```swift
extension NSObject: BindingExecutionContextProvider {
extension DisposeBagProvider {

public var bindingExecutionContext: ExecutionContext {
return .immediateOnMain
public var deallocated: SafeSignal<Void> {
return bag.deallocated
}
}
```

`ExecutionContext.immediateOnMain` executes synchronously if the current thread is main, otherwise it makes asynchronous dispatch to main queue.

If your type is a subclass of `NSObject`, you can always override `bindingExecutionContext` property to provide another context. On the other hand, if your type is not a subclass of `NSObject` all you need to do is conform to `BindingExecutionContextProvider`.
As you can see, `DisposeBagProvider` inherits `Deallocatable` and implements is by taking the deallocated signal from the bag. So all that you need to do is provide a `bag` property.

How do you conform to `Deallocatable`? The simplest way is conforming to `DisposeBagProvider` instead.
`BindingExecutionContextProvider` protocol provides the execution context in which the object should be updated. Execution context is just a wrapper over a dispatch queue or a thread. You can see how it is implemented [here](https://github.com/ReactiveKit/ReactiveKit/blob/master/Sources/ExecutionContext.swift).

```swift
/// A type that provides a dispose bag.
/// `DisposeBagProvider` conforms to `Deallocatable` out of the box.
public protocol DisposeBagProvider: Deallocatable {
public protocol BindingExecutionContextProvider {

/// A `DisposeBag` that can be used to dispose observations and bindings.
var bag: DisposeBag { get }
/// An execution context used to deliver binding events.
var bindingExecutionContext: ExecutionContext { get }
}
```

extension DisposeBagProvider {
> Bond framework provides `BindingExecutionContextProvider` conformance to various UIKit objects so they can be seamlessly bound to while ensuring the main thread.

public var deallocated: SafeSignal<Void> {
return bag.deallocated
You can conform to this protocol by providing execution context.

```swift
extension MyViewModel: BindingExecutionContextProvider {

public var bindingExecutionContext: ExecutionContext {
return .immediateOnMain
}
}
```

As you can see, `DisposeBagProvider` inherits `Deallocatable` and implements is by taking the deallocated signal from the bag. So all that you need to do is provide a `bag` property.
`ExecutionContext.immediateOnMain` executes synchronously if the current thread is main, otherwise it makes asynchronous dispatch to main queue. If you want to bind on background queue, you can return `.background` instead.

> Note that updating UIKit or AppKit objects must always happen from the main thread or queue.

Now we can peek into the binding implementation.

Expand Down
4 changes: 2 additions & 2 deletions ReactiveKit.podspec
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
Pod::Spec.new do |s|
s.name = "ReactiveKit"
s.version = "3.5.0"
s.version = "3.5.1"
s.summary = "A Swift Reactive Programming Framework"
s.description = "ReactiveKit is a Swift framework for reactive and functional reactive programming."
s.homepage = "https://github.com/ReactiveKit/ReactiveKit"
s.license = 'MIT'
s.author = { "Srdan Rasic" => "[email protected]" }
s.source = { :git => "https://github.com/ReactiveKit/ReactiveKit.git", :tag => "v3.5.0" }
s.source = { :git => "https://github.com/ReactiveKit/ReactiveKit.git", :tag => "v3.5.1" }

s.ios.deployment_target = '8.0'
s.osx.deployment_target = '10.9'
Expand Down
2 changes: 1 addition & 1 deletion ReactiveKit/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>3.5.0</string>
<string>3.5.1</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
Expand Down
10 changes: 0 additions & 10 deletions Sources/Bindable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -115,18 +115,8 @@ extension SignalProtocol where Error == NoError {
}

/// Provides an execution context used to deliver binding events.
///
/// `NSObject` conforms to this protocol be providing `ImmediateOnMainExecutionContext`
/// as binding execution context. Specific subclasses can override the context if needed.
public protocol BindingExecutionContextProvider {

/// An execution context used to deliver binding events.
var bindingExecutionContext: ExecutionContext { get }
}

extension NSObject: BindingExecutionContextProvider {

public var bindingExecutionContext: ExecutionContext {
return .immediateOnMain
}
}

0 comments on commit c5eaa28

Please sign in to comment.