2012-05-08 3 views
9

私はcocos2dのSimpleAudioEngineの機能をいくつかの種類の連鎖として次々と再生する機能を拡張しようとしています。私は拡張機能でこれをしようとしました。しかし、私は今、おそらくすべてのサウンドファイルの名前を覚えておくためにiVarと、現在再生中のサウンドを覚えておく必要があることに気付きました。Objective-Cカテゴリと新しい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 

は、代替的に、私がコンパイルされます特性としてアイバーズを定義しようとしました。しかし、私はそれらを合成することも、他の方法にバインドすることもできません。

SimpleAudioEngineのカテゴリとして機能を実装しようとするので、すべてのサウンドの問題を扱うクラスを1つだけ覚えておく必要があります。そして私は、このような単純なチェーンを作成することができます:

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

を、私も非常に感謝するのと同じ/同様の結果が得られ、別の方法がある場合。

+1

なぜSimpleAudioEngineをサブクラス化しないのですか? – lawicko

+0

[Objective-C:Categoryのプロパティ]の複製が可能です(http:// stackoverflow。com/questions/8733104/objective-c-property-in-category) – hfossli

答えて

22

インスタンス変数(または合成された@properties)をカテゴリに追加できないということは間違いありません。あなたの.hで

:あなたの.mで

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

#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 

あなたは、このようなAssociative References

何かのためのObjective-Cランタイムのサポートを使用して、この制限を回避することができます(標準的な免責事項が適用されます。これをブラウザに入力してテストしませんでしたが、以前はこの手法を使用していました)

私がリンクしたドキュメントには、連想参照がどのように機能するかについてのより多くの情報があります。

+0

私はiOSで作業していると忘れています。この情報をタグに追加しました。 iOSでは、このアプローチは禁止されています。これを達成する方法がまだあるかどうか、あるいは私が望む機能を提供する新しいクラスを作成する必要があるかどうかを知っていますか? –

+0

@gebirgsbaerbel:iOSで禁止されていますか?あなたはそれをどこで聞いたのですか? – Chuck

+0

@Chuckのドキュメントには、この機能はMacOS10.6以降で利用できると書かれています。また、私はそれを試して、私は基本的に2つの方法が知られていないというエラーを取得します。それらを含むヘッダーファイルは、iOS上に存在しないようです。多分私は何かを忘れた? –

-1

iVarsを追加することはできませんが、プロパティ変数を追加できます。以下のような 何か:あなたの.hで

:あなたの.mで

#import <objc/runtime.h> 

@interface Chair (Liking) 

    @property (nonatomic, assign)BOOL liked; 
@end 

#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 

そして、どこか他のいくつかのクラスでは

#import "Chair+ChairCat.h" 
- (void)viewDidLoad { 
    ///// 
    Chair *chair = [[Chair alloc] init]; 
    [chair setLiked:NO]; 
} 
myViewController.mを言います
関連する問題