Skip to content

Commit c2fda0b

Browse files
committed
updated documentation
closes #17
1 parent 46757c4 commit c2fda0b

4 files changed

Lines changed: 27 additions & 19 deletions

File tree

HISTORY.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
11
## [0.3.0][] • work in progress
22

33
- Updated to Swift 2.1 (Xcode 7.1).
4+
5+
- Made references to class-based subjects weak. This helps to remove
6+
subject-machine reference cycles, but it also means you have to keep a
7+
strong reference to a subject somewhere else (which you usually already do).
8+
When subject references become `nil`, transitions are no longer performed.
9+
Thanks to @bartekchlebek for work on this issue! :clap:
10+
411
- Added default `DOTLabel` implementation (`return "\(self)"`). You don't
512
have to change anything. If you have custom `DOTLabel` implementations,
613
you can keep using them, but if the only thing you do is `case Foo: return

README.md

Lines changed: 8 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,14 @@ Enjoy improving your code by explicitly defining distinct states and
277277
transitions between them! While you do so, please keep two things in
278278
mind:
279279

280-
1) Remember that [Swift `enum`s][enums] can have associated values — you
280+
1) Your subjects are probably reference types (classes). Storing a
281+
state machine as a property of a subject normally would create a reference
282+
cycle, so SwiftyStateMachine uses weak references for class-based subjects.
283+
This means you have to keep a strong reference to a subject somewhere else,
284+
but you usually already do this. When subject references become `nil`,
285+
transitions are no longer performed.
286+
287+
2) Remember that [Swift `enum`s][enums] can have associated values — you
281288
can pass additional information with events or store data in states.
282289
For example, if you had a game with a [heads-up display][HUD], you could
283290
do something like this:
@@ -297,22 +304,6 @@ machine.handleEvent(.TakeDamage(13.37))
297304
[HUD]: http://en.wikipedia.org/wiki/HUD_%28video_gaming%29
298305

299306

300-
2) If your subjects are reference types (classes), remember to use `unowned`
301-
to break reference cycles:
302-
303-
```swift
304-
let schema = // ...
305-
306-
class MyViewController: UIViewController {
307-
lazy var stateMachine = { [unowned self] in
308-
StateMachine(schema: schema, subject: self)
309-
}()
310-
311-
// ...
312-
}
313-
```
314-
315-
316307
Development
317308
-----------
318309

StateMachine/StateMachine.swift

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,11 @@ public struct StateMachineSchema<A, B, C>: StateMachineSchemaType {
5151
/// `StateMachineSchemaType` documentation for more information about schemas
5252
/// and subjects.
5353
///
54+
/// References to class-based subjects are weak. This helps to remove
55+
/// subject-machine reference cycles, but it also means you have to keep a
56+
/// strong reference to a subject somewhere else. When subject references
57+
/// become `nil`, transitions are no longer performed.
58+
///
5459
/// The state machine provides the `state` property for inspecting the current
5560
/// state and the `handleEvent` method for triggering state transitions
5661
/// defined in the schema.
@@ -83,7 +88,8 @@ public final class StateMachine<T: StateMachineSchemaType> {
8388
}
8489

8590
/// A method for triggering transitions and changing the state of the
86-
/// machine. If the transition logic of the schema defines a transition
91+
/// machine. Transitions are not performed when a weak reference to the subject
92+
/// becomes `nil`. If the transition logic of the schema defines a transition
8793
/// for current state and given event, the state is changed, the optional
8894
/// transition block is executed, and `didTransitionCallback` is called.
8995
public func handleEvent(event: T.Event) {
@@ -104,6 +110,10 @@ public final class StateMachine<T: StateMachineSchemaType> {
104110

105111

106112
public extension StateMachine where T.Subject: AnyObject {
113+
/// Creates a state machine with a weak reference to a subject. This helps
114+
/// to remove subject-machine reference cycles, but it also means you have
115+
/// to keep a strong reference to a subject somewhere else. When subject
116+
/// reference becomes `nil`, transitions are no longer performed.
107117
public convenience init(schema: T, subject: T.Subject) {
108118
self.init(schema: schema, subject: { [weak subject] in subject })
109119
}

StateMachineTests/StateMachineSpec.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ private class Subject {
5757
typealias SchemaType = StateMachineSchema<SimpleState, SimpleEvent, Subject>
5858

5959
let schema: SchemaType
60-
lazy var machine: StateMachine<SchemaType> = { [unowned self] in
60+
lazy var machine: StateMachine<SchemaType> = {
6161
StateMachine(schema: self.schema, subject: self)
6262
}()
6363

0 commit comments

Comments
 (0)