(前回)Cocoaの日々: Safari用独自プラグインを作る(2) - Posing と Method Swizzling
+[NSObject poseAsClass:] は 10.5 以降で Deprecated 扱いになっているようだが使ったことが無いので一応試しておこう。
Posing のコードは下記が参考になる。
junk(SafariWheelTab)
前回までにつくったひな形に NSWindow のサブクラスを一つ追加する。
XCWindow.h
#import@interface XCWindow : NSWindow { } @end
XCWindow.m
@implementation XCWindow - (void)sendEvent:(NSEvent *)theEvent { if ([theEvent type] == NSRightMouseDown) { NSLog(@"[1] NSRightMouseDown"); } [super sendEvent:theEvent]; } @end
これを +[load]メソッドで NSWindow と置き換える。
PluginController.m
#import "PluginController.h" #import "XCWindow.h" @implementation PluginController +(void)load { NSLog(@"+[PluginController load] was called"); [XCWindow poseAsClass:[NSWindow class]]; } @end
ビルドして所定の場所へ置いて Safariを再起動する。ウィンドウの上で右クリックすると..
出た。
ところでPosingを重ねた場合どんな挙動になるんだろうか。最初の Posingが無視されると他のプラグインが同じクラスを置き換えた場合困ったことになる。試しにもう一つクラスを用意して Posingを重ねてみた。
XCWindow2.m
@implementation XCWindow2 - (void)sendEvent:(NSEvent *)theEvent { if ([theEvent type] == NSRightMouseDown) { NSLog(@"[2] NSRightMouseDown"); } [super sendEvent:theEvent]; } @end
PluginController.m
#import "PluginController.h" #import "XCWindow.h" #import "XCWindow2.h" @implementation PluginController +(void)load { NSLog(@"+[PluginController load] was called"); [XCWindow poseAsClass:[NSWindow class]]; [XCWindow2 poseAsClass:[NSWindow class]]; } @end
実行してみると...
両方ともちゃんと呼び出されている。順番は後から Posingした方が先に呼び出されている。
(参考)
【コラム】ダイナミックObjective-C (12) ポージングで乗っ取り | エンタープライズ | マイコミジャーナル