From now on I will not be mentioning the disposal of the subscriber nor the error event because all the subjects behave in the same way in those situation.

Behavior Subject:

BehaviorSubject behaves almost the same as the publishSubject but we have to initialise it with a value. Why do we need a value at initialisation? Well, it is called seed/default value because every new subscriber to the behaviorSubject will receive the most recent element in the sequence. That element can be the seed/default value or the most recent value emitted by the source Observable.

Example:

Output with comments:

Next(Bob): This is the seed/default value, it is printed upon subscription of the fist subscriber

Next(Hello): emitted at line 13, printed by the first subscriber

Next(World): emitted at line 14, printed by the first subscriber

second subscription: Next(World) printed at line 17 by the second subscriber upon subscription.

Next(Ibrahim): emitted at line 23, printed by the first subscriber

second subscription: Next(Ibrahim): emitted at line 23, printed by the first subscriber

Replay Subject:

Sometimes we want to replay more than the most recent emitted event by the source Observable to the new subscribers. This is what ReplaySubject is capable of doing. To create a ReplaySubject, we need to declare a type because the initializer does not take an initial value. We can also call its static initializer createUnbounded() to create a ReplaySubject that replays all the previous emitted event, but be careful using it. I will leave you with the description of the method

Creates a new instance of ReplaySubject that buffers all the elements of a sequence. To avoid filling up memory, developer needs to make sure that the use case will only ever store a ‘reasonable’ number of elements.

Example:

In the above example I have created a RepalySubject with a buffer size equal to 2 `replaySubject<String>.create(bufferSize: 2)`, hence I will get only the last 2 emitted event by the source Observable.

Output with comments:

Next(A): emitted at line 4 before any subscription, printed upon subscription of the first subscriber.

Next(B): emitted at line 18, printed by the first subscriber.

Next(C): emitted at line 17, printed by the first subscriber.

Second subscription: Next(B): printed upon subscription of the second subscriber.

Second subscription: Next(C): printed upon subscription of the second subscriber.

Next(D): emitted at line 30, printed by the first subscriber.

Second subscription: Next(D): emitted at line 30, printed by the second subscriber.

Variable Subject: (Deprecated, will update soon)

Last subject to look at, which is a wrapper around another type of subject not a complete new one. It’s called a variable. What makes a variable special is that it is guaranteed to not terminate with an error. When a variable instance is about to be de-allocated it will automatically emit a completed event. We create a variable by passing an initial value to its initializer. Because the variable is a wrapper around the behavior subject, it will automatically replay only the last value to new subscribers.

Example:

Note how we add new element to the variable using the .value public property, which does not mutate the variable’s value. If you commad-click on it in Xcode you will see it sets the value to a new private property _value and adds the value to another private property that holds its behavior subject _subject value so that subscribers will be notified via a next event.

As you can see, when we call asObservable on the variable, it exposes the private subject behavior so we can subscribe for next events.

Output and comments:

Next(B): emitted at line 6, printed upon subscription of the first subscriber.

Next(C): emitted at line 12, printed by the first subscriber.

Second subscription: Next(C): emitted at line 12, printed by the second subscriber.

Completed: emitted upon deallocation of the first subscriber.

Second subscription: Completed: emitted upon deallocation of the second subscriber.