StateMachine-GCDThreadsafe 2.0.2

StateMachine-GCDThreadsafe 2.0.2

测试已测试
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
 

  • Luis Solano Bonet 和 brynd austin bellomy

// StateMachine-GCDThreadsafe

基于 Grand Central Dispatch 的线程安全的 iOS 状态机库。

该库受 Ruby 钻石 state_machine 和字母 5 的启发。

特性

  • 线程安全且快速。所有转换代码都在只有临界区的异步调度队列上的屏障块中执行。
  • 开放式架构。您还可以将您的块提交到该队列。所有内容都将通过底层的线程安全处理。
  • 简单、基于块的 DSL,用于定义您的类的状态机。基于块的 beforeafter 转换挂钩。
  • 写入更少的样板代码。动态生成所有状态机方法,直接在您的类中使用一些 Objective-C 运行时 voodoo jah。

安装

  1. CocoaPods 是方式和光明。只需将其添加到您的 Podfile

    pod 'StateMachine-GCDThreadsafe', '>= 2.0.0'
  2. 直接方法。您应该能够将 StateMachine 添加到您的源代码树中。创建一个包含您的项目的 Xcode 工作区,然后将其导入 StateMachine-GCDThreadsafe 项目中。

  3. 间接方法。如果您正在使用 Git,考虑使用 git submodule

说真的,立即使用 CocoaPods,好吗?

具有具体目标的用户的简单用法

让我们模拟一个 Subscription 类。

1. @interface

声明您的类符合 SEThreadsafeStateMachine 协议(如果您好奇,该协议定义在 LSStative.h 中)。

@interface Subscription : NSObject <SEThreadsafeStateMachine>
@property (nonatomic, strong, readwrite) NSDate *terminatedAt;
- (void) stopBilling;
@end

2. 的 @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. ...

3. 状态机 DSL

在类实现中,我们使用 StateMachine DSL 来定义我们的有效状态和事件。

  1. "该 DSL 是一个进行中的工作,将会有所改变。" - @luisobo
  2. "不懂,我觉得挺好的,真的。" - @brynbellomy
  3. 结论:*摊手*
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];
    }];
});

4. 指定初始化器

  1. 在你的指定初始化器(如:-init等)中使用 @gcd_threadsafe_init(...)。将其放在 if (self) 块中的其他任何内容之前。它接受两个参数,这两个参数都涉及到关键部分调度队列:
    • 其并发模式:SERIAL 或 CONCURRENT
    • 以及其标签:一个标准的 C 字符串
  2. 在此之后立即调用 [self initializeStateMachine]
  3. 来做吧
- (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 还会定义查询方法来检查对象是否处于给定状态(如 isPendingisActive 等)以及检查事件是否会触发有效转换(如 canActivatecanSuspend 等)。

触发事件

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"

它是否是重入的?

拜托,孩子,现在过来

贡献

  1. 熟悉一下ReactiveCocoa。这是这个代码分支极有可能前往的方向。
  2. fork 这个项目。
  3. 创建一个新的功能分支。
  4. 提交你的更改。
  5. 推送到分支。
  6. 创建新的拉取请求。

最高分