在Objective C中,A类可以是B类的委托,而B类是A类的委托吗?

时间:2017-05-25 18:25:27

标签: ios objective-c delegates

已编辑包含代码。

在Objective C中,是否可以让A类成为B类的委托,而B类是A类的委托?

我有第一个代表(称之为A到B)工作正常。然后我反过来实现它,它找不到委托方法,经典警告: 协议'SoundpaperViewControllerDelegate'中的方法'audioCueHasMovedDelegateMethod'未实现。

在我花时间上传代码之前,请告诉我这是否可行,我只是做错了,或者如果它不能起作用,我需要使用其他技术,如NSNotification。我已经完成了我的谷歌搜索,但找不到这个已发布的地址。

如果这在理论上是合法的,那么我将上传我的代码。

谢谢。

在目标C中,是否有可能将方法A委托给方法B,而方法B是方法A的委员会? 我有第一个代表(称之为A到B)工作正常。然后我反过来实现它,它找不到委托方法,经典警告: 协议'SoundpaperViewControllerDelegate'中的方法'audioCueHasMovedDelegateMethod'未实现。

在我花时间上传代码之前,请告诉我这是否可行,我只是做错了,或者如果它不能起作用,我需要使用其他技术,如NSNotification。我已经完成了我的谷歌搜索,但找不到这个发布的解决方案。 谢谢。 这是A类: A类AudioOperations,它调用类B,SoundpaperViewController中的方法,称为setupAudioPlayerControls。这是因为视图控制器与屏幕对话(使用Storyboard)。虽然我想将音频播放器分成单独的类和单独的文件以保持清洁。 这很好用

AudioOperations.h

. . .
@class AudioOperations;
@class SoundPaperViewController;


@protocol AudioOperationsDelegate <NSObject>

- (void) setupAudioPlayerControls;  // THIS is called on Class B and works fine



@end

@interface  AudioOperations : NSObject

@property (nonatomic, weak) IBOutlet id <AudioOperationsDelegate> delegate;
. . .

@end

Simplified AudioOperations.mm

@interface AudioOperations () <AVAudioPlayerDelegate>

@end


- (void) audioPlayback  // simplified to show what is important
{
    NSLog(@"Entering audioPlayback");
    self.audioPlayer.delegate = self;

        NSLog(@"calling setupaudioplayercontrols from audioPlayback");
            [self.delegate setupAudioPlayerControls];  // delegated to soundpaperviewcontroller and works just fine


    NSLog(@"Exiting audioPlayback");
}


. . . (various other code)
- (void) audioCueHasMovedDelegateMethod  // THIS IS THE method that should be called from Class B but can’t be found (where the warning comes from)
{
    // User has released the cue while inside the control - update the player…
    NSLog(@"in delegate audioCueHasMoved");
    [self.audioPlayer setCurrentTime: self.delegate.audioCueSlider.value];

    if (self.audioPlayer.isPlaying == NO)
    {
        [self.audioPlayer play];
    }

    // … and go back to updating the control.

    self.audioTimer = [NSTimer scheduledTimerWithTimeInterval: 0.1
                                                       target: self
                                                     selector: @selector(updateAudioTime:)
                                                     userInfo: nil
                                                      repeats: YES];
}

这是B类(再次简化)

SoundpaperViewController.h
. . .

@class LabelProcessor;
@class AudioOperations;
@class SpotterGraphicsView;

@protocol SoundpaperViewControllerDelegate <NSObject>

- (void) audioCueHasMovedDelegateMethod;  // this is the method that should be called but isn’t found

@end


@interface SoundPaperViewController : UIViewController<QLPreviewControllerDataSource, QLPreviewControllerDelegate>

@property (nonatomic, weak) IBOutlet id <SoundpaperViewControllerDelegate> delegate;

. . .

@end


SoundpaperViewController.mm
. . . (bunch of #imports etc)
@interface SoundPaperViewController () <AVCaptureVideoDataOutputSampleBufferDelegate
    ,AVCaptureMetadataOutputObjectsDelegate
    ,LabelProcessorDelegate
    ,AudioOperationsDelegate
    ,SettingsObserver
    ,CEGuideArrowDelegate
    ,SoundpaperViewControllerDelegate  // NOT SURE THIS IS RIGHT, but I’ve tried it with and without it
    >
. . . (bunch of @properties, etc.)
@implementation SoundPaperViewController  // WARNING IS HERE that the method  audioCueHasMovedDelegateMethod  can’t be found


- (id) initWithCoder: (NSCoder*) inDecoder
{
    if ((self = [super initWithCoder: inDecoder]) != nil)
    {
        NSLog(@"new latestImageCond created NEW");
        self.latestImageCondition = [NSCondition new];
        NSLog(@"initWithCoder spvc thread: %@", [NSThread currentThread]);
    }

    self.delegate = self;  // NOTE this

    return self;
}


// This is the delegate method called from CLASS A (AudioOperations) and works just fine:
- (void) setupAudioPlayerControls
{

    NSLog(@"setupAudioPlayerControls");
    // hide the playbutton
    [self.playButton setEnabled:NO];
    [self.playButton setTintColor: [UIColor clearColor]];  // hides it

. . . etc.


}

尽可能接近我在两个类中都完成了相同的操作(除了我不确定是否在界面中使用此SoundpaperViewControllerDelegate之外。

感谢您解决这些混乱的代码。我确定我错过了一些明显的东西!

2 个答案:

答案 0 :(得分:2)

是的,这可以做到。确保每个人都对另一个人有弱引用,这样你就不会有一个保留周期。

答案 1 :(得分:0)

在朋友的帮助下,我能够让它发挥作用。对于那些可能遇到类似问题的人来说,这是设置正确的.h文件的问题:

在SoundpaperViewController.h中:

@class LabelProcessor;
@class AudioOperations;
@class SoundPaperViewController;


@interface SoundPaperViewController : UIViewController < QLPreviewControllerDataSource, QLPreviewControllerDelegate>  // note no audioOperationsDelegate in this line

- (void) setupAudioPlayerControls;

@property (nonatomic, strong) AudioOperations * SPVdelegate;

在AudioOperations类中:

@class AudioOperations;
@class SoundPaperViewController;

@interface  AudioOperations : NSObject  // note no SoundpaperViewControllerDelegate here

@property (nonatomic, weak)   SoundPaperViewController * audioDelegate;

- (void) audioCueHasMovedDelegateMethod;

在Soundpaper类.m文件中:

_myAudio = [[AudioOperations alloc] init];
_myAudio.audioDelegate = self;
self.SPVdelegate = _myAudio;

我很有启发,我不需要在@interface中包含委托(例如@interface SoundpaperViewController)摆脱它并简单地声明@property就是所需要的。