ヒレガス本第四版第9章 NSUndoManagerの覚え書き

NSInvocationについて

たった半ページでNSInvocationを説明をしている。予備知識が無いと理解出来ない。 NSInvocationを理解するには「詳細Objective-C 2.0第3版」 p385を参照する事。

[NSUndoManager prepareWithInvocationTarget:self]について

[NSUndoManager prepareWithInvocationTarget:self]の返り値はid型です。

この返り値がid型である為に、どのようなメッセージを投げられてもコンパイル時にはエラーにはなりません。

そのため、ヒレガス本の例にあるように簡潔にコードが書けます。

- (void) insertObject:(Person*)inPerson
   inEmployeesAtIndex:(NSUInteger)inIndex
{
    NSUndoManager* theUndoMgr  = [self undoManager];

    // この行はid型に対してメッセージを送っている
    [[theUndoMgr prepareWithInvocationTarget:self]
        removeObjectFromEmployeesAtIndex:inIndex];

    if( ![theUndoMgr isUndoing] )
    {
        [theUndoMgr setActionName:@"Add Person"];
    }

    [employees insertObject:inPerson atIndex:inIndex];
}

より防衛的に書く場合は、型チェックをすり抜ける上記のような書き方はよくない。 以下のように型を指定した書き方をした方がよい。

- (void) insertObject:(Person*)inPerson
   inEmployeesAtIndex:(NSUInteger)inIndex
{
    NSUndoManager* theUndoMgr  = [self undoManager];
    RMDocument*    theInstance = [theUndoMgr prepareWithInvocationTarget:self];

    // RMDocumentの型にする事で凡ミスが減る
    [theInstance removeObjectFromEmployeesAtIndex:inIndex];

    if( ![theUndoMgr isUndoing] )
    {
        [theUndoMgr setActionName:@"Add Person"];
    }

    [employees insertObject:inPerson atIndex:inIndex];
}