Objective-C类别和新的iVar

我尝试将cocos2d的SimpleAudioEngine的function扩展为能够连续播放几种音效的function。 我试图用扩展名来做到这一点。 然而,我现在意识到,我可能还需要一个iVar记住所有声音文件的名称,并记住哪个声音正在播放。

但是,似乎我不能在一个类别中添加iVars。 相反,我试图使用扩展名,但似乎他们需要在类的原始.m文件,这样也行不通。 有没有另外一种方法,让我做到这一点?

标题与类别

#import <Foundation/Foundation.h> @interface SimpleAudioEngine(SoundChainHelper)<CDLongAudioSourceDelegate> -(void)playSoundChainWithFileNames:(NSString*) filename, ...; @end 

和扩展名为.m的文件:

 #import "SoundChainHelper.h" @interface SimpleAudioEngine() { NSMutableArray* soundsInChain; int currentSound; } @end @implementation SimpleAudioEngine(SoundChainHelper) // read in all filenames and start off playing process -(void)playSoundChainWithFileNames:(NSString*) filename, ... { soundsInChain = [[NSMutableArray alloc] initWithCapacity:5]; va_list params; va_start(params,filename); while (filename) { [soundsInChain addObject:filename]; filename = va_arg(params, NSString*); } va_end(params); currentSound = 0; [self cdAudioSourceDidFinishPlaying:nil]; } // play first file, this will also always automatically be called as soon as the previous sound has finished playing -(void)cdAudioSourceDidFinishPlaying:(CDLongAudioSource *)audioSource { if ([soundsInChain count] > currentSound) { CDLongAudioSource* mySound = [[CDAudioManager sharedManager] audioSourceForChannel:kASC_Right]; [mySound load:[soundsInChain objectAtIndex:0]]; mySound.delegate = self; [mySound play]; currentSound++; } } @end 

或者我试图将iVars定义为属性,它将被编译。 但是我既不能把它们综合起来,也没有其他的可能性来把它们绑定到任何方法上。

我尝试将这个function作为SimpleAudioEngine的一个类来实现,这样我只需要记住一个处理所有声音问题的类。 所以我可以创build一个这样简单的链:

 [[SimpleAudioEngine sharedEngine] playSoundChainWithFileNames:@"6a_loose1D.mp3", @"6a_loose2D.mp3", @"6a_loose3D.mp3", @"6a_loose4D.mp3", @"6b_won1D.mp3", nil]; 

如果有另外一种方法可以产生相同/相似的结果,我也会非常感激。

你是正确的,你不能添加实例variables(或综合@properties)到一个类别。 您可以使用Objective-C运行时对关联引用的支持来解决这个限制

像这样的东西:

在你的.h:

 @interface SimpleAudioEngine (SoundChainHelper) @property (nonatomic, retain) NSMutableArray *soundsInChain; @end 

在你的.m:

 #import <objc/runtime.h> static char soundsInChainKey; @implementation SimpleAudioEngine (SoundChainHelper) - (NSMutableArray *)soundsInChain { return objc_getAssociatedObject(self, &soundsInChainKey); } - (void)setSoundsInChain:(NSMutableArray *)array { objc_setAssociatedObject(self, &soundsInChainKey, array, OBJC_ASSOCIATION_RETAIN_NONATOMIC); } @end 

(标准声明适用,我在浏览器中input了这个声明,但是没有testing,但是我之前使用过这个技术。)

我链接到的文档有更多关于联想参考如何工作的信息。

你不能添加iVars,但可以添加属性variables。 如下所示:

在你的.h:

 #import <objc/runtime.h> @interface Chair (Liking) @property (nonatomic, assign)BOOL liked; @end 

在你的.m:

 #import "Chair+ChairCat.h" @implementation Chair (Liking) -(BOOL)liked{ return [ objc_getAssociatedObject( self, "_aliked" ) boolValue ] ; } -(void)setLiked:(BOOL)b{ objc_setAssociatedObject(self, "_aliked", [ NSNumber numberWithBool:b ],OBJC_ASSOCIATION_RETAIN_NONATOMIC ) ; } @end 

然后在某个其他类的某个地方说myViewController.m

 #import "Chair+ChairCat.h" - (void)viewDidLoad { ///// Chair *chair = [[Chair alloc] init]; [chair setLiked:NO]; }