- (void)tryToStartSound:(NSSound *)sound ofType:(UCC3AudioType)type { UCC3AssertMainThread; if (!self.ammActiveRecording) { CSULogDebug(@"Will try to play sound %p of type %@ on device %@ with volume %.2f", sound, [UCC3ValueToString stringWithUCC3AudioType:type], sound.playbackDeviceIdentifier, sound.volume); [sound setCurrentTime:0]; if ([sound play]) { [self setNumberOfStartRetriesCount:0 forType:type]; CSULogDebug(@"Successfully started sound %p of type %@", sound, [UCC3ValueToString stringWithUCC3AudioType:type]); } else { NSInteger currentRetries = [self numberOfStartRetriesForType:type]; if (currentRetries < MAX_START_STOP_RETRIES) { CSULogWarn(@"Failed to start sound %p of type %@. Will retry", sound, [UCC3ValueToString stringWithUCC3AudioType:type]); UCC3DefineWeakSelf; NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{ UCC3DefineStrongSelf; [self setNumberOfStartRetriesCount:currentRetries+1 forType:type]; [self tryToStartSound:sound ofType:type]; }]; [self.operationQueue performSelector:@selector(addOperation:) withObject:operation afterDelay:UCC3AudioHelperRetryDelay]; } else { CSULogError(@"Gave up trying to start sound %p", sound); [self setNumberOfStartRetriesCount:0 forType:type]; self.playbackStateForAudioTypeMap[@(type)] = @(NO); } } } else { self.playbackStateForAudioTypeMap[@(type)] = @(NO); CSULogWarn(@"Won't play sound of type %@ due to active AMM recording", [UCC3ValueToString stringWithUCC3AudioType:type]); } } It is called as below : UCC3DefineWeakSelf; [self.operationQueue addOperationWithBlock:^{ UCC3DefineStrongSelf; [self tryToStartSound:sound ofType:type]; }]; Definition of UCC3DefineWeakSelf as below #define UCC3DefineWeakSelf __weak typeof(self) weakSelf = self