已编辑包含代码。
在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之外。
感谢您解决这些混乱的代码。我确定我错过了一些明显的东西!
答案 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就是所需要的。