カテゴリを使ってプロトコルの後付け

Objective-Cでは、ひとまとまりのメソッド群が実装されているかを実行時に調べる方法として、プロトコルと呼ばれる物がある。

私は、まず「プロトコル」が存在し、それに対して「プロトコルに適応されたクラス」が存在すると考えていた。

しかし、Objective-Cでは、既存のクラスを後付けでプロトコルに適応出来ました。

以下のコードを実行するとログに”:-D”が表示されます。

#import "PTAppDelegate.h"

// プロトコルの定義
@protocol PTObjectValueProtocol
- (void)setObjectValue:(id<NSCopying>)obj;
- (id)objectValue;
@end

// プロトコルを後付けするカテゴリ
@interface NSControl (PTAppDelegate) <PTObjectValueProtocol>
@end
// 後付けしたプロトコルの実装
@implementation NSControl (PTAppDelegate)
@end

@implementation PTAppDelegate
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
    // "protocol(PTObjectValueProtocol)"の部分は@protocolです。
    // sphinxがうまくコードを色づけしてくれなかったので@を抜かしました。
    if( [NSButton conformsToProtocol:protocol(PTObjectValueProtocol) ] )
    {
        NSLog(@":-D");
    }
    else
    {
        NSLog(@":-(");
    }
}
@end

基本的に、

  • “@interface 既存クラス名 (カテゴリ名) <プロトコル名>”
  • “@implementation 既存クラス名 (カテゴリ名)”

の2つを作るだけで問題なくプロトコル対応なクラスとして認識してくれました。

久しぶりに神保町

先日、仕事帰りに神保町の明倫館書店に行った。

店の中を物色していると、床の上に積まれている本の中に欲しい物が有った。

値段はいくらなのか店員に尋ねると、整理中なので触らないで欲しいとの事。

次に寄り道する時には売れてしまっているのだろうなと思いつつ店を出る。

validateuserinterfaceitem(6)

続き。

NSMatrixやNSForm等の複数のNSCellのインスタンスを持つControlの取り扱いに難儀中。

NSMenuItem, NSToolBarItem, NSButton等は”- (IBAction) action:(id)sender”の引数にそれぞれのObjectが来る。

選択余地はないのでこれは正しい。

しかし、NSMatrixはsenderにNSMatrixが入るのは正しいのだろうか?もちろんCocoaの実装では、NSMatrixが入っている。

Radioボタン等はtagをとる為に、NSCellがsenderに入るのが”正しい”気がするのだが。

今日は眠いので寝る。

validateUserInterfaceItem(5)

さらに続き。

MTLControlItemEnablerをもっと拡張する

以下の属性のアップデートにも対応した。

  • attributedTitle
  • objectValue
  • stringValue
  • attributedStringValue
  • toolTip

NSMatrixに対応出来ていない

MTLControlItemEnablerはNSMatrixに対応出来ていません。 ラジオボタングループのstateを変更が出来ません。

おそらく、NSMatrixのサブクラスでMTLButtonのようにupdateをする事と、matrix内部のcellのstateを変更するように拡張すれば動くと思われる。

が、まだ手つかず。

サンプルコード

かなり中途半端だが、一応UPする

EnablerTest-4.zip