自作セレクタークラスの改良


先日自作したクラスに色々と仕入れた情報を試してみました。

プロトコルの継承

プロトコルの宣言をして引き継ぎたいプロトコルをカンマ,区切りで書くと継承できるらしい。


@protocol selector
<UIPickerViewDataSource,UIPickerViewDelegate,UIActionSheetDelegate>
@optional
-(void)testmessage;
@end

この状態にして呼び出し元のクラスのインターフェースのスーパークラスに続けて'<selector>’をつける。

これでそれぞれのプロトコルを引き継いだ上で独自のプロトコルに対応できるようになる。

独自のプロトコルに対応するにはもうひとつ手順が必要になる。

プロトコル型のインスタンス変数

id <selector> _myDelegate;
@property(nonatomic,assign) id<selector> myDelegate;

この2つを宣言する、こうしておくことでmyDelegateにはプロトコルに対応していない変数をセットするとコンパイル時に警告が出る。

それから呼び出し元でsetMyDelegate:selfとする。
こうしておいてに内部メソッドの中で[[self myDelegate] testmessage];を送ってあげる。

-(void)testButton{
if (_myDelegate respondsToSelector:@selector(testmessage)) {
[[self myDelegate] testmessage];
}
}

メッセージを送る前にメソッドに対応しているかをチェックしておく。この時にプロトコルへの対応を調べる[_myDelegate conformsToProtocol:<#(Protocol *)#>]というメソッドもあるのですがこっちだと実際にメソッドを持っていなくても通ってしまうらしいのでselectorの方でチェックする。

あとは呼び出し元で-(void)testmessage;に対応すればOK。
myDelegateになっているのはUIActionSheetを継承しているのでインスタンス変数名がかぶってしまうので単純にdelegateをつかえないのでこうしてあります。これをさけてdelegateという名前を使うにはNSobjectを継承して今回のような組み合わせをつくればできるのかも。

次の課題はdelegateへのセットが多すぎな件への対応

現時点でアクションシートやピッカーへのデリゲートなどに対応しつつ自作クラスでのメソッド委譲(デリゲート)できるようになりました。しかし現時点ではデリゲートが多すぎて呼び出し元のコードがこんなかんじに

_selector=[[Q66Selector alloc] initWithFrame:CGRectMake(0, 0, 0, 0) callClass:self];
[_selector setMyDelegate:self];
[_selector setDelegate:self];
[_selector.picker setDelegate:self];
[_selector.picker setDataSource:self];

もうどれがどれだかわかりません。これはmyDelegateのみにしてクラス内部でセットするコードにしたほうがよさそうですね。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です