iOS 状态模式中循环引用导致Expected a type 错误

什么状态模式?就是允许对象在内部状态改变时改变它的行为,对象看起来好像修改了它的类。
举个栗子!你有一个类GumballMachine你在它里面定义了一个枚举State,然后给State 设置了四种状态A、B、C、D。之后在你的Machine.M类中可能会这么做if(State==A){

-(void)insertQuarter;

-(void)ejectQuarter;

state= B; //大致是执行完2个方法以后改变状态为B
}else if(state==B){

-(void)turnCrank;

state = C;

}
一次类推。。。 以后可能还会出现更多的状态。
这时我们可以尝试一下改变!把状态执行的方法都放到一个协议里(接口)

@protocol custumState <NSObject>//状态映射为具体对象、可选实现的方法@optional

@required // 必须实现的方法

-(void)insertQuarter;

-(void)ejectQuarter;

-(void)turnCrank;

-(void)dispense;

@end

这时我们把枚举类型的各个状态分别对应着一个类,而这个类必须实现我们上面的这个接口,而这个类里执行的方法就是我们原来state==A下面执行的方法,例如A 对应 类MySoldState , 其实通过栗子可以看出,状态类里方法的实现和状态的切换其实是通过GumballMachine 类来实现的。

#import "custumState.h"

#import "GumballMachine.h"

@interface MySoldState : NSObject<custumState>

-(instancetype)initWithMachine:(id)gumballMachine; //这里参数用id 而不用GumballMachine* 是因为GumballMachine类里会含有MySoldState的对象,为了避免循环引用所以用id.

@end

它的实现:

#import "MySoldState.h"

@interface MySoldState()

@property(nonatomic,strong)GumballMachine * gbm;

@end

@implementation MySoldState

-(instancetype)initWithMachine:(id)gumballMachine{

    self= [super init];

    if (self) {

        self.gbm = gumballMachine;

    }

    return self;

}

- (void)dispense {

    [self.gbm releaseBall];

    if (self.gbm.count>0) {

         [self.gbm setState:self.gbm.noQuarterState];

    }

    else{

         [self.gbm setState:self.gbm.soldOutState];

    }

}

- (void)ejectQuarter {

     NSLog(@"noThing");

}

- (void)insertQuarter {

     NSLog(@"you inserted a quarter");

    

}

- (void)turnCrank {

     NSLog(@"noThing");

}

主要的类

GumballMachine.h

#import "custumState.h"

#import "MySoldState.h" //举例子用的其中一个 下面的三个和这个一样

#import "SoldOutState.h"

#import "NoQuarterState.h"

#import "HasQuarterStates.h"

@interface GumballMachine : NSObject

@property(nonatomic) id<custumState> state; //相当于枚举类型的 变量

@property(nonatomic,strong) id<custumState> soldState; //实现协议的对象 相当于枚举类型里的具体类型

@property(nonatomic,strong) id<custumState> soldOutState;

@property(nonatomic,strong) id<custumState> noQuarterState;

@property(nonatomic,strong) id<custumState> hasQuarterStates;

@property(nonatomic)int count;

-(void)setState:(id<custumState>)state; //用来实现状态的转换

-(void)releaseBall;

-(instancetype)initWithQuarter:(int)numberGumballs; //用于初始化此类

@end

GumballMachine.m

@implementation GumballMachine

-(instancetype)initWithQuarter:(int)numberGumballs{

    self = [super init];

    if (self) {

        _soldOutState = [[SoldOutState alloc] initWithMachine:self]; //初始化状态类

        _noQuarterState = [[NoQuarterState alloc] initWithMachine:self];

        _hasQuarterStates = [[HasQuarterStates alloc] initWithMachine:self];

        _soldState = [[MySoldState alloc] initWithMachine:self];

        _count = numberGumballs;

        _state = _soldOutState; //把状态对象 赋予相应的实际值

        if (_count>0) {

            _state = _noQuarterState;

        }

    }

    return self;

}

//投进5分钱

-(void)insertQuarter{

    [_state insertQuarter];

}

//退回5分钱

-(void)ejectQuarter{

    [_state ejectQuarter];

}

//转动曲柄

-(void)turnCrank{

    [_state turnCrank];

    [_state dispense];

}

-(void)setState:(id<custumState>)state{

    _state = state;

}

-(void)releaseBall{

    NSLog(@"a gumball comes rolling out the solt..");

    if (_count!=0) {

        _count= _count-1;

    }

}

@end

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值