2017-05-25 8 views
0

コードを編集しました。Objective Cでは、クラスAはクラスBの代理人であり、クラスBはクラスAの代理人ですか?

Objective Cでは、クラスAをクラスBの代理人にすることができますが、クラスBはクラスAの代理人ですか?

私は最初のデリゲート(AからBと呼んでください)が正常に動作しています。私は、他の方法で回避それを実装し、それは古典的な警告とデリゲートメソッド、見つけることができません。 メソッドプロトコルの「audioCueHasMovedDelegateMethod」「SoundpaperViewControllerDelegate」実装されていませんが。

コードをアップロードする前に、これが可能かどうか、私はちょうど間違ったことをしていますか、最初にうまくいかず、別のテクニックNSNotificationとして。私は私のグーグルで行ったことがありますが、これが発行されたことがわかりません。

これは理論的には合法であるならば、私は自分のコードをアップロードします。

ありがとうございます。

Objective Cでは、メソッドAをメソッドBに委譲することができますが、メソッドBはメソッドAに限定されていますか?
私は最初のデリゲート(AからBと呼ぶ)をうまく動作させています。私は、他の方法で回避それを実装し、それは古典的な警告とデリゲートメソッド、見つけることができません。 メソッドプロトコルの「audioCueHasMovedDelegateMethod」「SoundpaperViewControllerDelegate」実装されていませんが。

コードをアップロードする前に、これが可能かどうか、私はちょうど間違ったことをしていますか、最初にうまくいかず、別のテクニックNSNotificationとして。私は私のグーグルで行ったことがありますが、これが発行されたことがわかりません。 ありがとうございます。 これはCLASS A IS: クラスA AudioOperations、これはsetupAudioPlayerControlsと呼ばれ、クラスB、SoundpaperViewController、中にメソッドを呼び出します。これは、View Controllerが画面に何を伝えているか(Storyboardsを使用しているため)です。私は、オーディオプレーヤーを別のクラスに分け、ファイルを分離して清潔にしたいと思っています。 これはうまく動作します

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 

簡体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. 


} 

IS私は両方のクラスですべてを同じようにしたことを伝えます。インタフェースでこのSoundpaperViewControllerDelegateを使用するかどうかわからないということです。

は、コードのこの混乱を通じて作業をありがとうございました。私は明らかな何かが欠けていると確信しています!

+2

「デリゲート」は言語機能ではなく、単なるデザインパターンであり、双方向性を含め、必要なすべての方法で作成できます。 – luk2302

+4

それは絶対に可能です。しかし、あなたが知っているようにそれを弱くしてください。それ以外のサイクルは起こります –

+0

ありがとう、それは私が考えたものです。私は今、コードサンプルを書いています、ありがとう。 – user938797

答えて

0

。同様の問題を抱えている人には、.hファイルを正しく設定することが重要でした。

SoundpaperViewControllerにあります。H:AudioOperationsクラスで

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


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

- (void) setupAudioPlayerControls; 

@property (nonatomic, strong) AudioOperations * SPVdelegate; 

@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のような)@interfaceの代理人それを取り除き、単に@propertyを宣言するだけで、必要なものがすべて得られました。

2

はい、これは可能です。それぞれが弱い参照を持っていることを確認してください。そうすれば、保持サイクルに陥ることはありません。私はこの仕事を得ることができた友人の助けを借りて

+1

1つだけ弱い参照である必要があります。そしてもし彼らが両方とも弱ければ、何か他のものを所有する必要があります。 –

関連する問題