在completionblock中改变一个变量



你好,我目前有问题桥接变量在我的完成块。我想在完成块中将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:看起来像一个按钮事件回调,释放它不会有任何好处;读)。

因此我建议:

  1. 取消CFRelease()呼叫
  2. myself转换为类:MyClass *myclass = (MyClass *)myself; .
  3. 调用myclass.previewPlaying = NO;(假设它是属性)。呼叫[myclass previewNotPlaying](见下文)。
  4. self代替sender传给AudioServicesAddSystemSoundCompletion()

EDIT说了这些,我现在看到您正在使用按钮实例来显示信息。不调用上面的属性,而是调用实例上的一个方法,并让该方法完成工作:

- (void)previewNotPlaying
{
    // _previewButton is an IBOutlet to the button
    [_previewButton setTitle:@"Preview" forState:UIControlStateNormal];
    _isPreviewPlaying = NO;
}

最新更新