2012-05-08 24 views
9

Tôi cố gắng mở rộng chức năng của SimpleAudioEngine của cocos2d với khả năng phát một số hiệu ứng âm thanh cái khác như một số loại chuỗi. Tôi đã cố gắng làm điều này với một phần mở rộng. Tuy nhiên bây giờ tôi nhận ra rằng tôi có lẽ cũng cần một iVar để nhớ tên của tất cả các tập tin âm thanh và một để nhớ âm thanh hiện đang chơi.Mục tiêu-C Danh mục và iVar mới

Tuy nhiên có vẻ như tôi không thể thêm iVars vào danh mục. Thay vào đó tôi đã cố gắng sử dụng một phần mở rộng, nhưng có vẻ như họ cần phải ở trong tập tin .m ban đầu của lớp để cũng không hoạt động. Có cách nào khác, điều đó cho phép tôi làm điều này không?

Các tiêu đề với các loại

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

Và .m-file với phần mở rộng:

#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 

Ngoài ra tôi đã cố gắng để xác định Ivars như tài sản, mà sẽ biên dịch. Tuy nhiên tôi không thể tổng hợp chúng cũng như tôi không có khả năng khác để ràng buộc chúng với bất kỳ phương pháp nào.

Tôi cố gắng triển khai chức năng dưới dạng danh mục của SimpleAudioEngine để tôi chỉ cần nhớ một lớp có giao dịch với tất cả các vấn đề âm thanh của mình. và để tôi có thể tạo một chuỗi đơn giản như thế này:

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

Nếu có cách khác mang lại kết quả tương tự/tương tự, tôi cũng rất biết ơn.

+1

Tại sao không phân lớp SimpleAudioEngine? – lawicko

+0

có thể trùng lặp của [Mục tiêu-C: Thuộc tính trong Danh mục] (http: // stackoverflow.com/questions/8733104/objective-c-property-in-category) – hfossli

Trả lời

22

Bạn đúng là bạn không thể thêm biến mẫu (hoặc tổng hợp @properties) vào danh mục. Bạn có thể workaround hạn chế này sử dụng hỗ trợ thời gian chạy Objective-C cho Associative References

Something như thế này:

Trong .h của bạn:

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

Trong .m của bạn:

#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 

(Việc từ chối tiêu chuẩn được áp dụng. Tôi đã nhập vào trình duyệt này và không thử nghiệm nó, nhưng trước đây tôi đã sử dụng kỹ thuật này.)

Tài liệu tôi liên kết có nhiều thông tin hơn về cách hoạt động của các tham chiếu liên kết.

+0

Tôi quên nói rằng tôi đang làm việc trên iOS. Bây giờ tôi đã thêm thông tin này vào các thẻ. Trên iOS, phương pháp này bị cấm. Bạn có biết liệu vẫn còn cách để đạt được điều này hay tôi cần tạo một lớp mới cung cấp chức năng tôi muốn? –

+0

@gebirgsbaerbel: Đã chặn trên iOS? Nơi mà bạn đã nghe thấy không? – Chuck

+0

@Chọn trong tài liệu hướng dẫn cho biết tính năng này khả dụng trên MacOS10.6 và mới hơn. Ngoài ra tôi đã thử nó ra và tôi về cơ bản nhận được lỗi mà hai phương pháp không được biết đến. Tệp tiêu đề chứa chúng dường như không tồn tại trên iOS. Có lẽ tôi đã bỏ lỡ một cái gì đó? –

-1

Bạn không thể thêm iVars nhưng có thể thêm biến thuộc tính. Something như dưới đây:

Trong .h của bạn:

#import <objc/runtime.h> 

@interface Chair (Liking) 

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

Trong .m của bạn:

#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 

Sau đó, ở đâu đó trong một số lớp khác nói myViewController.m

#import "Chair+ChairCat.h" 
- (void)viewDidLoad { 
    ///// 
    Chair *chair = [[Chair alloc] init]; 
    [chair setLiked:NO]; 
} 
Các vấn đề liên quan