ページ

2007年8月31日金曜日

NSView#dragImage:... を使う

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク

NSView の

- (void)dragImage:(NSImage *)anImage at:(NSPoint)viewLocation offset:(NSSize)initialOffset event:(NSEvent *)event pasteboard:(NSPasteboard *)pboard source:(id)sourceObj slideBack:(BOOL)slideFlag;

を使って、アプリ内外のドラッグ&ドロップを統一的に処理する方法を調査中。


あるカスタムビュー(仮に View1とする)で上記メソッドを実行すると処理はそこでブロックされる。例えば:

[self dragImage:drag_img at:p offset:NSZeroSize
event:event pasteboard:pb source:self slideBack:NO]; --> 終了までブロック

NSLog(@"end");


を実行すると、ドラッグ&ドロップが終わるまで "end"がログに出力されない。

このドラック&ドロップ中のイベントを拾う必要があるのだが NSDraggingDestination(非形式プロトコル)を実装してやるとあっさり取ることができた。NSDraggingDestinationの主要メソッドは6つある。

– draggingEntered:
– draggingUpdated:
– draggingExited:
– prepareForDragOperation:
– performDragOperation:
– concludeDragOperation:


ところでここで疑問が生じてくる。dragImage:.. は処理が終わるまでブロックされているのだから NSDraggingDestination のメソッド群は別スレッドから呼ばれるのか?そうなると排他制御が必要になるな、と。

そこで dragImage:... と draggingEntered: の両方で下記のコードを入れて様子を見てみると:
NSLog(@" %@, %@", self, [NSThread currentThread]);


結果はどちらも同じだった。

2007-08-31 12:34:04.439 DragSample[5671] , {num = 1, threadDictionary =
{type = mutable, count = 1, capacity = 4, pairs = (
1 : {contents = "NSAppleEventManagerHandlingStack"} = {type = mutable-small, count = 0, values = (
)}
)}
}


つまり dragImage:... と同じスレッドから draggingEntered: が呼び出されていることになる。


とりあえずは一歩前進。