测试已测试 | ✗ |
Lang语言 | Obj-CObjective C |
许可 | MIT |
Release上次发布 | 2014 年 12 月 |
由 无人维护 维护。
依赖于 | |
libextobjc/EXTScope | >= 0.2.5 |
libextobjc/EXTSynthesize | >= 0.2.5 |
libextobjc/EXTBlockMethod | >= 0.2.5 |
libextobjc/NSMethodSignature+EXT | >= 0.2.5 |
BrynKit/Main | >= 1.2.1 |
BrynKit/GCDThreadsafe | >= 1.2.1 |
基于 Grand Central Dispatch 的线程安全的 iOS 状态机库。
该库受 Ruby 钻石 state_machine 和字母 5 的启发。
before
和 after
转换挂钩。CocoaPods 是方式和光明。只需将其添加到您的 Podfile
pod 'StateMachine-GCDThreadsafe', '>= 2.0.0'
直接方法。您应该能够将 StateMachine 添加到您的源代码树中。创建一个包含您的项目的 Xcode 工作区,然后将其导入 StateMachine-GCDThreadsafe
项目中。
git submodule
。说真的,立即使用 CocoaPods,好吗?
让我们模拟一个 Subscription
类。
声明您的类符合 SEThreadsafeStateMachine
协议(如果您好奇,该协议定义在 LSStative.h
中)。
@interface Subscription : NSObject <SEThreadsafeStateMachine>
@property (nonatomic, strong, readwrite) NSDate *terminatedAt;
- (void) stopBilling;
@end
@gcd_threadsafe
宏。@gcd_threadsafe
定义在 <BrynKit/GCDThreadsafe.h>
中。导入它。该宏本身应放置在您的 @implementation
块中。最好是放在顶部,这样它就有更多的自我文档化。
该宏在您的类上定义了几个方法,用于将临界区代码调度到 self.queueCritical
-- 这是杀手级功能,主要吸引力 -- 这是 GITTAN RIAL 的私有 dispatch_queue_t
。
#import <BrynKit/GCDThreadsafe.h>
@implementation Subscription
@gcd_threadsafe
// methods, etc. ...
在类实现中,我们使用 StateMachine
DSL 来定义我们的有效状态和事件。
STATE_MACHINE(^(LSStateMachine *sm) {
sm.initialState = @"pending";
[sm addState:@"pending"];
[sm addState:@"active"];
[sm addState:@"suspended"];
[sm addState:@"terminated"];
[sm when:@"activate" transitionFrom:@"pending" to:@"active"];
[sm when:@"suspend" transitionFrom:@"active" to:@"suspended"];
[sm when:@"unsuspend" transitionFrom:@"suspended" to:@"active"];
[sm when:@"terminate" transitionFrom:@"active" to:@"terminated"];
[sm when:@"terminate" transitionFrom:@"suspended" to:@"terminated"];
[sm before:@"terminate" do:^(Subscription *self){
self.terminatedAt = [NSDate dateWithTimeIntervalSince1970:123123123];
}];
[sm after:@"suspend" do:^(Subscription *self) {
[self stopBilling];
}];
});
-init
等)中使用 @gcd_threadsafe_init(...)
宏。将其放在 if (self)
块中的其他任何内容之前。它接受两个参数,这两个参数都涉及到关键部分调度队列:[self initializeStateMachine]
。- (id) init
{
self = [super init];
if (self) {
@gcd_threadsafe_init(CONCURRENT, "com.pton.KnowsHowToParty.queueCritical");
[self initializeStateMachine];
}
return self;
}
@gcd_threadsafe_init(...)
初始化 self.queueCritical
属性。
一旦给定特定的转换和状态配置,StateMachine-GCDThreadsafe 将动态地向你的类中添加适当的方法以反映该配置。你会发现你面临一些有关这些方法的编译器警告。想要让编译器闭嘴?很简单:定义一个类范畴,并且不要实现它。这个范畴可以生活在实现文件中(如果需要私有方法),在头文件中(如果希望方法可以被公开调用),或者两者之间分散。
@interface Subscription (StateMachine)
- (void)initializeStateMachine;
- (BOOL)activate;
- (BOOL)suspend;
- (BOOL)unsuspend;
- (BOOL)terminate;
- (BOOL)isPending;
- (BOOL)isActive;
- (BOOL)isSuspended;
- (BOOL)isTerminated;
- (BOOL)canActivate;
- (BOOL)canSuspend;
- (BOOL)canUnsuspend;
- (BOOL)canTerminate;
@end
除了你的类的主要 state
属性支持 KVO 可观察性外,StateMachine 还会定义查询方法来检查对象是否处于给定状态(如 isPending
、isActive
等)以及检查事件是否会触发有效转换(如 canActivate
、canSuspend
等)。
Subscription *subscription = [[Subscription alloc] init];
subscription.state; // will be set to @"pending", the value of the initialState property
开始触发事件...
[subscription activate]; // retuns YES because it's a valid transition
subscription.state; // @"active"
[subscription suspend]; // also, `-stopBilling` is called by `-suspend`
// retuns YES because it's a valid transition
subscription.state; // @"suspended"
[subscription terminate]; // retuns YES because it's a valid transition
subscription.state; // @"terminated"
subscription.terminatedAt; // [NSDate dateWithTimeIntervalSince1970:123123123];
但是!如果我们触发一个无效事件...
// the subscription is now suspended
[subscription activate]; // returns NO because it's not a valid transition
subscription.state; // @"suspended"
拜托,孩子,现在过来