ページ

2008年7月8日火曜日

isEqual と compare:

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

ウィンドウを管理する為に WindowNumber という簡単なクラスを作る。

@interface WindowNumber : NSObject {
int _order;
CGWindowID _window_id;
}
-(int)order;
-(CGWindowID)windowID;
@end


メンバ変数としてウィンドウの並び順(_order)と、WindowIDを持つ。このクラスのオブジェクトを NSMutableArrayで管理する。
この時、同じオブジェクトが配列に既に含まれているかといったチェックと、_orderを使った配列のソートを行いたい。前者は NSArray#containsObject: を後者は NSMutableArray#sortUsingSelector: を使えば実現できる。ただし、それぞれ必要なメソッドを用意しておく必要がある。

(1) containsObject: への対応
リファレンス によるとオブジェクトの同値チェックには NSObject#isEqual: が使われるとのこと。WindowNumber でこれをオーバーライドしてやれば良い。

こんな感じ。WindowNumberの同値性は _window_id でのみ判断する(並び順は無視する)。
- (BOOL)isEqual:(id)anObject
{
if (anObject == self) {
return YES;
}
if (!anObject || ![anObject isKindOfClass:[self class]]) {
return NO;
}
if (_window_id != [anObject windowID]) {
return NO;
}
return YES;
}


これで containsObject: が意図通りに動作するようになる。


(2) sortUsingSelector: への対応
リファレンスによるとオブジェクトを比較するメソッドを追加してやれば良いとのこと。戻り値は比較結果に応じて下記のようになる。

 NSOrderedAscending、NSOrderedDescending、NSOrderedSame

メソッドは次の様に実装した。_orderで並び順を決定する。
- (NSComparisonResult)compare:(WindowNumber*)wn
{
int order = [wn order];
if (_order < order) {
return NSOrderedAscending;
} else if (_order > order) {
return NSOrderedDescending;
}
return NSOrderedSame;
}


その上で WindowNumberのオブジェクトを格納した NSMutableArray へ sortUsingSelector: を呼出せば良い。
(例)[array sortUsingSelector:@selector(compare:)];


- - - -
現在複数ウィンドウの同時キャプチャを実装していて、その中でこのクラスを使う。