From 5f8b3ff28527cd0edaa298432efad6fba354b678 Mon Sep 17 00:00:00 2001 From: Michael Kirk Date: Tue, 3 Apr 2018 11:54:55 -0400 Subject: [PATCH] Object lifecycle disposes SystemSound // FREEBIE --- SignalMessaging/environment/OWSSounds.m | 65 +++++++++++++++++++------ 1 file changed, 50 insertions(+), 15 deletions(-) diff --git a/SignalMessaging/environment/OWSSounds.m b/SignalMessaging/environment/OWSSounds.m index 09600990e..9e29a8653 100644 --- a/SignalMessaging/environment/OWSSounds.m +++ b/SignalMessaging/environment/OWSSounds.m @@ -14,10 +14,51 @@ NSString *const kOWSSoundsStorageNotificationCollection = @"kOWSSoundsStorageNotificationCollection"; NSString *const kOWSSoundsStorageGlobalNotificationKey = @"kOWSSoundsStorageGlobalNotificationKey"; +@interface OWSSystemSound : NSObject + +@property (nonatomic, readonly) SystemSoundID soundID; +@property (nonatomic, readonly) NSURL *soundURL; + +- (instancetype)init NS_UNAVAILABLE; +- (instancetype)initWithURL:(NSURL *)url NS_DESIGNATED_INITIALIZER; + +@end + +@implementation OWSSystemSound + +- (instancetype)initWithURL:(NSURL *)url +{ + self = [super init]; + + if (!self) { + return self; + } + + DDLogDebug(@"%@ creating system sound for %@", self.logTag, url.lastPathComponent); + _soundURL = url; + + SystemSoundID newSoundID; + OSStatus status = AudioServicesCreateSystemSoundID((__bridge CFURLRef _Nonnull)(url), &newSoundID); + OWSAssert(status == kAudioServicesNoError); + OWSAssert(newSoundID); + _soundID = newSoundID; + + return self; +} + +- (void)dealloc +{ + DDLogDebug(@"%@ in dealloc disposing sound: %@", self.logTag, _soundURL.lastPathComponent); + OSStatus status = AudioServicesDisposeSystemSoundID(_soundID); + OWSAssert(status == kAudioServicesNoError); +} + +@end + @interface OWSSounds () @property (nonatomic, readonly) YapDatabaseConnection *dbConnection; -@property (nonatomic, readonly) AnyLRUCache *cachedSoundIDs; +@property (nonatomic, readonly) AnyLRUCache *cachedSystemSounds; @end @@ -55,7 +96,7 @@ NSString *const kOWSSoundsStorageGlobalNotificationKey = @"kOWSSoundsStorageGlob _dbConnection = primaryStorage.newDatabaseConnection; // Don't store too many sounds in memory. Most users will only use 1 or 2 sounds anyway. - _cachedSoundIDs = [[AnyLRUCache alloc] initWithMaxSize:3]; + _cachedSystemSounds = [[AnyLRUCache alloc] initWithMaxSize:3]; OWSSingletonAssert(); @@ -220,24 +261,18 @@ NSString *const kOWSSoundsStorageGlobalNotificationKey = @"kOWSSoundsStorageGlob - (SystemSoundID)systemSoundIDForSound:(OWSSound)sound quiet:(BOOL)quiet { NSString *cacheKey = [NSString stringWithFormat:@"%lu:%d", (unsigned long)sound, quiet]; - NSNumber *_Nullable cachedSoundId = (NSNumber * _Nullable)[self.cachedSoundIDs getWithKey:cacheKey]; + OWSSystemSound *_Nullable cachedSound = (OWSSystemSound *)[self.cachedSystemSounds getWithKey:cacheKey]; - if (cachedSoundId) { - OWSAssert([cachedSoundId isKindOfClass:[NSNumber class]]); - return (SystemSoundID)cachedSoundId.intValue; + if (cachedSound) { + OWSAssert([cachedSound isKindOfClass:[OWSSystemSound class]]); + return cachedSound.soundID; } NSURL *soundURL = [self.class soundURLForSound:sound quiet:quiet]; + OWSSystemSound *newSound = [[OWSSystemSound alloc] initWithURL:soundURL]; + [self.cachedSystemSounds setWithKey:cacheKey value:newSound]; - DDLogVerbose(@"%@ creating system sound for %@", self.logTag, soundURL.lastPathComponent); - SystemSoundID newSoundID; - OSStatus status = AudioServicesCreateSystemSoundID((__bridge CFURLRef _Nonnull)(soundURL), &newSoundID); - OWSAssert(status == 0); - OWSAssert(newSoundID); - - [self.cachedSoundIDs setWithKey:cacheKey value:@(newSoundID)]; - - return newSoundID; + return newSound.soundID; } #pragma mark - Notifications