2012-01-30 14 views
5

मुझे आशा है कि शीर्षक बहुत भ्रामक नहीं है का उपयोग कर ... :)AudioServicesAddSystemSoundCompletion __bridge

मैं इतना है कि यह करने के लिए एक प्रणाली ध्वनि चलाने और जोड़ने SoundCompletion-कॉलबैक:

AudioServicesAddSystemSoundCompletion(soundID, NULL, NULL, completionCallback, (__bridge_retained void *)self); 

«जबकि स्वयं »एक सरल NSObject

पूरा होने के कॉलबैक में मैं फिर से खेल दिनचर्या कॉल करने के लिए कोशिश है:

मैं __bridge_transfer और जोड़ने के लिए किया था _ cbridge को _bridge_retained, अन्यथा मुझे त्रुटियों, दुर्घटनाओं, या अन्य अप्रत्याशित व्यवहार मिलता है।

लेकिन पूरी चीज इसके बावजूद काम नहीं करती है।

मैं एनएसएमयूटेबलएरे में खेलने के लिए ध्वनि संग्रहीत करता हूं, सरणी की पहली प्रविष्टि पकड़ता हूं और इसे चलाता हूं, ध्वनि पूर्णता जोड़ता हूं और आशा करता हूं कि सामान होता है। - लेकिन सब है कि बनाए रखा हस्तांतरण सामग्री के साथ, NSMutableArray दूसरी कॉल पर खाली है ...

कोड यह रहा:

static void completionCallback (SystemSoundID mySSID, void *myself) { 

    NSLog(@"Audio callback"); 

    AudioServicesRemoveSystemSoundCompletion (mySSID); 
    AudioServicesDisposeSystemSoundID(mySSID); 

    [(__bridge_transfer Speaker *)myself speakCharacter]; 

    CFRelease(myself); // I heard I need this? 

} 

-(void)speakCharacter{ 

    if([sounds count] > 0){ 

     NSString *soundToPlay = [sounds objectAtIndex:0]; 
     [sounds removeObjectAtIndex:0]; 
     NSLog(@"TxtToSpeak %@", soundToPlay); 
     CFURLRef  soundFileURLRef; 
     NSURL *path = [[NSBundle mainBundle] URLForResource:[soundToPlay uppercaseString] withExtension:@"aif"]; 
     soundFileURLRef = (__bridge CFURLRef)path; 
     SystemSoundID soundID; 
     AudioServicesCreateSystemSoundID(soundFileURLRef, &soundID); 
     AudioServicesAddSystemSoundCompletion(soundID, NULL, NULL, completionCallback, (__bridge_retained void *)self); 
     AudioServicesPlaySystemSound (soundID); 
    } 
} 

[संपादित करें] - मेरी खुद सवाल का जवाब:

इसे स्वयं ढूंढने के लिए हमेशा अच्छा लगा :)

बाहर निकलता है, मैं लगभग वहां था।

कॉलबैक स्थापित करने के लिए कॉल इस प्रकार है:

AudioServicesAddSystemSoundCompletion(soundID, NULL, NULL, completionCallback, (__bridge_retained void *)self); 

फिर, कॉलबैक-समारोह में, मैं यह कर:

myClass *theClass = (__bridge myClass *)myself; 
    CFRelease(myself); 
    [theClass playNextSound]; // The routine that plays the sounds 

और यह काम करता है ...

+0

उत्तर के लिए धन्यवाद, वास्तव में मेरी मदद की! हालांकि इसे लगभग याद किया गया है, क्योंकि प्रश्न अनुत्तरित दिखाई देता है - क्या आपको अपने प्रश्न का उत्तर जोड़ने की अनुमति है? या मैं इसे अपनी टिप्पणियों पर इंगित कर सकता हूं? चीयर्स वी वैसे भी;] – davidfrancis

उत्तर

8

मैं अपने स्वयं के प्रश्न का उत्तर नहीं दे सका क्योंकि मैं स्टैक ओवरफ्लो के लिए बहुत तेज़ था - इसलिए इसे पूरा करने के लिए, मैं फिर से जवाब जोड़ता हूं :)

बाहर निकलता है, मैं लगभग वहां था।

कॉलबैक स्थापित करने के लिए कॉल इस प्रकार है:

AudioServicesAddSystemSoundCompletion(soundID, NULL, NULL, completionCallback, (__bridge_retained void *)self); 

फिर, कॉलबैक-समारोह में, मैं यह कर:

myClass *theClass = (__bridge myClass *)myself; 
CFRelease(myself); 
[theClass playNextSound]; // The routine that plays the sounds 

और यह काम करता है ...

+0

क्या कोई कारण है कि आप केवल __bridge का उपयोग नहीं कर सकते हैं? मुझे इस विधि के साथ ऑब्जेक्ट तक पहुंचने में दुर्घटनाएं मिलती हैं। –

+0

मेरे लिए काम करता है। @AlastairStuart मुझे लगता है कि बिंदु तब होता है जब आप ऑब्जेक्ट को 'ऑडियो सर्विसेज एड सिस्टम सिस्टमसाउंडप्लिप्शन' पर पास करते हैं, तो आप __bridge_retained करते हैं जो 1 से 1 तक बनाए रखेगा। __bridge कोई स्वामित्व हस्तांतरण की गारंटी नहीं देता है, इसलिए काउंटर कॉलबैक में वही रहेगा। CFRelease फिर 1 को बनाए रखेगा और अंततः ऑब्जेक्ट को हटा देगा। – Andy

+0

क्या 'खुद' के विपरीत CFRelease 'theClass' पर नहीं होगा? – shim

4

किसी भी व्यक्ति के लिए जो थोड़ी अतिरिक्त सहायता की ज़रूरत है ... मुझे स्विसड्यूड के सामान्य दृश्य नियंत्रक में काम करने का उत्तर मिला:

ध्यान दें: (आप CFRelease (अपने आप) का उपयोग नहीं कर सकते हैं)

#import <UIKit/UIKit.h> 
#import <AudioToolbox/AudioToolbox.h> 

@interface MYVIEWCONTROLLERNAME : UIViewController 

@property SystemSoundID mySentenceAudio; 

@end 

।एम

#import "MYVIEWCONTROLLERNAME.h" 

@interface MYVIEWCONTROLLERNAME() 
{ 
    int myLetterCount; 
    int myWordLength; 
} 
@end 

@implementation MYVIEWCONTROLLERNAME 

@synthesize mySentenceAudio; 


    #pragma mark - Click Action 

- (IBAction)SpellButtonPress:(UIButton *)sender { 
    [self AudioDataAndPlayerLoader]; 
    myLetterCount = 0; 
} 

# pragma mark - Audio Data 

-(void) AudioDataAndPlayerLoader { 

    NSString*myWord = @"apple"; 
    myWordLength = myWord.length; 
    NSArray*wordArray= [self stringToLetterArray:myWord]; 

    if (myWordLength > myLetterCount) { 
     NSString* myLetter = [wordArray objectAtIndex:myLetterCount]; 
     [self playMySound:myLetter]; 
    } 
} 

- (NSArray*)stringToLetterArray:(NSString*)string { 
    NSUInteger characterCount = [string length]; 
    NSMutableArray *temparray = [NSMutableArray arrayWithCapacity:[string length]]; 
    for (int i = 0; i<characterCount; i++) 
    { 
     [temparray addObject:[string substringWithRange:NSMakeRange (i,1)]]; 
    } 
    return [temparray copy]; 
} 

#pragma mark - Audio Loop 

- (void) myAudioLoopCheck { 
    myLetterCount++; 
    NSLog(@"Audio Looped"); 
    if (myWordLength > myLetterCount) { 
     [self performSelector:@selector(AudioDataAndPlayerLoader) withObject:nil afterDelay:.2]; 
    } 
    else { 
     NSLog(@"Done"); 
     myLetterCount = 0; 
    } 
} 

#pragma mark - Audio Player 

- (void) playMySound: (NSString*)soundTitle{ 

    NSString* SOUNDPATH = [[NSBundle mainBundle] 
          pathForResource:soundTitle 
          ofType:@"m4a" 
          inDirectory:@"audio/abc/"]; 
    if (SOUNDPATH != nil) { 

     CFURLRef baseURL = (__bridge_retained CFURLRef) [[NSURL alloc] initFileURLWithPath:SOUNDPATH]; 
     AudioServicesCreateSystemSoundID (baseURL, &mySentenceAudio); 

     AudioServicesPlaySystemSound(mySentenceAudio); 
     CFRelease(baseURL); 

     AudioServicesAddSystemSoundCompletion (mySentenceAudio,NULL,NULL,theAudioServicesSystemSoundCompletionProc,(__bridge void*)self); 
    } 
    else { 
    } 
} 

#pragma mark - Audio Player Callback 

static void theAudioServicesSystemSoundCompletionProc (SystemSoundID mySentenceAudio, void *myself) { 
    NSLog(@"Audio callback"); 
    AudioServicesRemoveSystemSoundCompletion (mySentenceAudio); 
    AudioServicesDisposeSystemSoundID(mySentenceAudio); 

    MYVIEWCONTROLLERNAME *theClass = (__bridge MYVIEWCONTROLLERNAME *)myself; 
    [theClass myAudioLoopCheck]; 
} 

// life cycle code...