您的位置:首页 > 移动开发 > IOS开发

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

2018-01-10 14:02 239 查看
什么状态模式?就是允许对象在内部状态改变时改变它的行为,对象看起来好像修改了它的类。
举个栗子!你有一个类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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息