你好,我目前有问题桥接变量在我的完成块。我想在完成块中将isPreviewPlaying
设置为NO,但是我不能。
static void completionCallback (SystemSoundID mySSID, void *myself) {
AudioServicesRemoveSystemSoundCompletion (mySSID);
AudioServicesDisposeSystemSoundID(mySSID);
CFRelease(myself);
UIButton *previewButton = (__bridge UIButton*)myself;
[previewButton setTitle:@"Preview" forState:UIControlStateNormal];
_isPreviewPlaying = NO // I want to do this, but I can't.
}
- (void)previewButtonPressed:(id)sender {
if (_isPreviewPlaying) {
_isPreviewPlaying = NO;
NSLog(@"STOP");
AudioServicesDisposeSystemSoundID(soundID);
} else {
NSString * selectedPreviewSound = [self.soundFile objectAtIndex: _soundFileIndex];
AudioServicesCreateSystemSoundID((__bridge CFURLRef)[NSURL fileURLWithPath: selectedPreviewSound], &soundID);
AudioServicesPlaySystemSound (soundID);
_isPreviewPlaying = YES;
AudioServicesAddSystemSoundCompletion(soundID, NULL, NULL, completionCallback, (__bridge_retained void *)sender);
[sender setTitle:@"Stop" forState:UIControlStateNormal];
}
}
您需要将类实例传递给完成块函数,因为它是一个C函数,这样您就可以访问实例上的属性和方法。
这是myself
参数的意图,我相信,但是你目前使用CFRelease()
释放它,因为某种原因我无法理解(我假设sender
是一个按钮,因为previewButtonPressed:
看起来像一个按钮事件回调,释放它不会有任何好处;读)。
因此我建议:
- 取消
CFRelease()
呼叫 - 将
myself
转换为类:MyClass *myclass = (MyClass *)myself;
. -
调用。呼叫myclass.previewPlaying = NO;
(假设它是属性)[myclass previewNotPlaying]
(见下文)。 - 将
self
代替sender
传给AudioServicesAddSystemSoundCompletion()
。
EDIT说了这些,我现在看到您正在使用按钮实例来显示信息。不调用上面的属性,而是调用实例上的一个方法,并让该方法完成工作:
- (void)previewNotPlaying
{
// _previewButton is an IBOutlet to the button
[_previewButton setTitle:@"Preview" forState:UIControlStateNormal];
_isPreviewPlaying = NO;
}