web-dev-qa-db-ja.com

Objective Cでデリゲートのプロトコルを拡張し、オブジェクトをサブクラス化して適合デリゲートを要求する方法

UITextViewをサブクラス化し、デリゲートに新しいメッセージを送信したいと思います。そこで、デリゲートプロトコルを拡張したいと思います。これを行う正しい方法は何ですか?

私はこれから始めました:

インターフェース:

_#import <Foundation/Foundation.h>

@class MySubClass;

@protocol MySubClassDelegate <UITextViewDelegate>
- (void) MySubClassMessage: (MySubClass *) subclass;
@end


@interface MySubClass : UITextView {
}

@end
_

実装:

_#import "MySubClass.h"


@implementation MySubClass

- (void) SomeMethod; { 
    if ([self.delegate respondsToSelector: @selector (MySubClassMessage:)]) { 
        [self.delegate MySubClassMessage: self];
    }
}

@end
_

ただし、それで警告が表示されます:'-MySubClassMessage:' not found in protocol(s)

デリゲートを格納するために独自のivarを作成し、_[super setDelegate]_を使用してデリゲートも格納するという、1つの方法がありましたが、それは間違っているように見えました。おそらくそうではありません。

IDを渡して通り抜けることができることはわかっていますが、私の目標は、MySubClassに提供されたデリゲートがMySubClassDelegateプロトコルに準拠していることをコンパイラーがチェックすることを確認することです。

さらに明確にするために:

_@interface MySubClassTester : NSObject {

}

@implementation MySubClassTester

- (void) one { 
    MySubClass *subclass = [[MySubClass alloc] init];
    subclass.delegate = self;
}

@end
_

警告が表示されます:_class 'MySubClassTester' does not implement the 'UITextViewDelegate' protocol_

代わりに「MySubClassDelegate」プロトコルを実装しないことについての警告を生成したいと思います。

31
fess .

まだ興味のある人は、これを次のように簡単に行うことができます(例として、UIScrollViewをサブクラス化します)。

@protocol MySubclassProtocol <UIScrollViewDelegate>
@required
-(void)myProtocolMethod;
@end

@interface MySubClass : UIScrollView

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

ここで最も重要な詳細は、プロトコル名の後の<>の間の部分です。これは、簡単に言えば、そのプロトコルを拡張していることを示します。実装では、次に行う必要があるのは次のとおりです。

@synthesize delegate;

これで完了です。

7
Ricardo Pedroni

スーパープロトコルを拡張する必要があります。

@protocol MYClassProtocol <SuperClassProtocol>
-(void)foo;
@end

その後DO N'T(!!!)デリゲート用に@ propertyを作成します。それ以外の場合は、元のデリゲートオブジェクトをオーバーライドしますが、メソッドをオーバーライドするだけです。

- (id<MYClassProtocol>)delegate
{
    return (id<MYClassProtocol>)[super delegate];
}

これで、従来の方法でデリゲートを使用できます。

[self.delegate foo];
[self.delegate someSuperClassDelegateMethod];
2
Kappe

MySubClassMessage:がオプションであるとすると、単純な次のことを簡単に実行できるはずです。

- (void) SomeMethod { 
  SEL delegateSelector = @selector(MySubClassMessage:);
  if ([self.delegate respondsToSelector:delegateSelector]) { 
    [self.delegate performSelector:delegateSelector withObject:self];
  }
}

コンパイラーは、実装クラスがプロトコルに準拠していること(または少なくともヘッダーで要求していること)を引き続きチェックする必要があり、説明したエラーは発生しません。

1