今天升级过程中原本跑得好好的代码老会炸掉,经比对发现是因为新版比旧版多了点儿东西。
if( [_parent conformsToProtocol:@protocol(CCRGBAProtocol)] && [(id<CCRGBAProtocol>)_parent isCascadeColorEnabled] )
报错原因是isCascadeColorEnabled这个unrecognized selector sent to了一个CCControlButton,这个错误我懂,是说明CCControlButton这个类没有实现isCascadeColorEnabled,可是这个是在CCRGBAProtocol里面规定的,然后CCControlButton又明明白白从实现了这个协议的CCControl派生而来,否则if前面的条件也不会通过,怎么就会有问题呢?
我对比了cocos2d-x的C++代码,这里protocol自然是通过一个抽象类来实现,里面的isCascadeColorEnabled是个纯虚函数,这样我理解肯定需要在派生类里面实现否则编译都通不过,果然在CCNode这个基类里面就给出了一个实现。怀疑Objective-C那边有类似的需求,可是我没法判断这个是不是一个类似纯虚函数的东西,然后全局一搜isCascadeColorEnabled,也没见别人实现啊,只好求教同事。
求教得知:
1.Protocol就相当于一个抽象类,里面的方法全相当于纯虚函数,都是需要实现的。
2.实现的方法是@synthesize cascadeColorEnabled = _cascadeColorEnabled就可以了,我带着is搜,所以搜不到。
3.如果不想实现,想判断这个类有实现才调用后面的方法,则可以使用respondsToSelector进行判断。
4.之所以可以编译通过运行时才报错是因为Protocol那里相当于给出声明了,只等你实现,而我没实现,但是也没显式通过这个类调用,所以是可以编译的,但是运行时动态获取到了这个类,就会出错了。