可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
Started a Cocos2D 2.1 template (with no physics engine) in Xcode 4.5, targeted for iOS 6 and iPad. In the CDAudioManager.m file, the following code...
AVAudioSession* session = [AVAudioSession sharedInstance]; session.delegate = self; // Which is what is automatically generated by the template.
...generates the following warning...
"delegate deprecated: first deprecated in iOS 6"
So I go to the apple developer documentation, and it says under "delegate," "Deprecated in iOS 6.0. Use the notifications described in the Notifications section of this class instead."
http://developer.apple.com/library/ios/#documentation/AVFoundation/Reference/AVAudioSession_ClassReference/DeprecationAppendix/AppendixADeprecatedAPI.html#//apple_ref/occ/instp/AVAudioSession/delegate
Problem is, it looks to me like all we're trying to do--forgive my inexperience--is set the delegate for the AVAudioSession to the CDAudioManager instance itself. How do the notifications accomplish this? Or am I just wrong about the goal of the above code?
回答1:
The error you are running into is in this block of code
AVAudioSession* session = [AVAudioSession sharedInstance]; session.delegate = self;// <-------- DEPRECATED IN IOS 6.0
To silence the warning change those 2 lines to this:
[[AVAudioSession sharedInstance] setActive:YES error:nil];
Hope this helps.
回答2:
Instead of using delegate use notification for handling as follows
[AVAudioSession sharedInstance]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(interruption:) name:AVAudioSessionInterruptionNotification object:nil]; - (void) interruption:(NSNotification*)notification { NSDictionary *interuptionDict = notification.userInfo; NSUInteger interuptionType = (NSUInteger)[interuptionDict valueForKey:AVAudioSessionInterruptionTypeKey]; if (interuptionType == AVAudioSessionInterruptionTypeBegan) [self beginInterruption]; else if (interuptionType == AVAudioSessionInterruptionTypeEnded) [self endInterruption]; }
回答3:
I found a poast about this on the Cocos2D-iPhone.org forums. While I don't fully understand it--but I'm working on it--it did seem to take care of the problem, at least temporarily. What he did was write this method in the CDAudioManger.m file:
-(void) releaseBufferForFile:(NSString *) filePath { int bufferId = [self bufferForFile:filePath create:NO]; if (bufferId != kCDNoBuffer) { [soundEngine unloadBuffer:bufferId]; [loadedBuffers removeObjectForKey:filePath]; NSNumber *freedBufferId = [[NSNumber alloc] initWithInt:bufferId]; [freedBufferId autorelease]; [freedBuffers addObject:freedBufferId]; } } @end - (void) interruption:(NSNotification*)notification { NSDictionary *interuptionDict = notification.userInfo; NSNumber* interuptionTypeValue = [dict valueForKey:AVAudioSessionInterruptionTypeKey]; NSUInteger interuptionType = [interuptionTypeValue intValue]; if (interuptionType == AVAudioSessionInterruptionTypeBegan) [self beginInterruption]; #if __CC_PLATFORM_IOS >= 40000 else if (interuptionType == AVAudioSessionInterruptionTypeEnded) [self endInterruptionWithFlags:(NSUInteger)[interuptionDict valueForKey:AVAudioSessionInterruptionOptionKey]]; #else else if (interuptionType == AVAudioSessionInterruptionTypeEnded) [self endInterruption]; #endif }
Then he replaced:
AVAudioSession *session = [AVAudioSession sharedInstance]; session.delegate = self;
with this:
[AVAudioSession sharedInstance]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(interruption:) name:AVAudioSessionInterruptionNotification object:nil];
Here's the link: http://www.cocos2d-iphone.org/forum/topic/49956
If and when I develop a better understand of what this code is doing, I'll be sure to edit this post.
回答4:
I haven't tested this but according to this post: http://www.cocos2d-iphone.org/forums/topic/cdaudiomanager-line-402-delegate-is-deprecated/#post-390211
float osVersion = [[UIDevice currentDevice].systemVersion floatValue]; if (osVersion >=6.0) { [AVAudioSession sharedInstance]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(interruption:) name:AVAudioSessionInterruptionNotification object:nil]; } else { AVAudioSession* session = [AVAudioSession sharedInstance]; session.delegate = self; }
I.e. throw different code runtime depending on iOS version.
Now, my app is iOS 6.0+ only anyway so I'll just go with:
[AVAudioSession sharedInstance]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(interruption:) name:AVAudioSessionInterruptionNotification object:nil];
And cross my thumbs.