NSUndoManager не работает.Аарон Хиллегасс глава 9 - PullRequest
0 голосов
/ 27 октября 2011

Я работал над программированием какао для Mac OS X Аароном Хиллегасом. Я застрял в главе 9. Я добавил 2 метода, необходимых для вызова функций отмены и возврата. Однако, когда я собираю и запускаю приложение, согласно книге, методы должны вызываться автоматически, но это не так. Они написаны правильно, как вы можете видеть ниже ...

2 дополнительных метода в MyDocument.m

- (void)insertObject:(Person *)p inEmployeesAtIndex:(int)index
{
    NSLog(@"Adding %@ to %@", p, employees);
        //Add the inverse of this operation to the undo stack
    NSUndoManager *undo = [self undoManager];
    [[undo prepareWithInvocationTarget:self]removeObjectFromEmployeesAtIndex:index];
    if (![undo isUndoing]){
        [undo setActionName:@"Insert Person"];
    }
        //Add teh person to the array
    [employees insertObject:p atIndex:index];
}

- (void)removeObjectFromEmployeesAtIndex:(int)index
{
    Person *p = [employees objectAtIndex:index];
    NSLog(@"Removing %@ to %@", p, employees);
        //Add the inverse of this operation to the undo stack
    NSUndoManager *undo = [self undoManager];
    [[undo prepareWithInvocationTarget:self]insertObject:p inEmployeesAtIndex:index];
    if (![undo isUndoing]){
        [undo setActionName:@"Delete Person"];
    }
    [employees removeObjectAtIndex:index];
}

myDocument.h

#import <Cocoa/Cocoa.h>
@class Person;

@interface MyDocument : NSDocument
{
    NSMutableArray *employees;
}
- (void)setEmployees:(NSMutableArray *)a;
- (void)removeObjectFromEmployeesAtIndex:(int)index;
- (void)insertObject:(Person *)p inEmployeesAtIndex:(int)index;
@end

Любая помощь будет отличной, спасибо:)

Ответы [ 3 ]

0 голосов
/ 27 октября 2011

В качестве альтернативы, если вы не используете KVC для доступа к этому свойству, вам необходимо убедиться, что вы используете средства доступа к массиву для доступа к нему.

Если при сохранении, восстановлении или применении изменений, вы говорите с массивом напрямую ([employees setArray:] или [employees insertObject:… atIndex…] / [employees removeObjectAtIndex:…]), тогда побочные эффекты ваших методов доступа не происходят, потому что вы их не использовали.Вы реализовали поддержку отмены в ваших средствах доступа (по крайней мере, в двух, чьи реализации вы показали), и, если что-то наблюдает за свойством через KVO, это еще один побочный эффект;обе эти вещи не происходят, если вы не используете свои методы доступа.

Если ваш метод доступа setEmployees: не общается с Undo Manager (вы пропустили этот код в своем вопросе, поэтому я не могу сказать,), то это не добавит отмены действий.Диспетчер отмены будет работать нормально, если вы с ним разговариваете, но если нет, то он не может.

Вы должны отправить себе insertObject:inEmployeesAtIndex: и removeObjectFromEmployeesAtIndex: сообщения, чтобы изменения былизаписано в менеджере отмены, если это единственные места, где вы говорите с менеджером отмены.Если вы хотите, чтобы оптовая замена (setEmployees:) была отменена, вы также должны добавить к ней отмену действия для менеджера.

0 голосов
/ 27 октября 2011

Я нашел проблему. Мой контроллер массива не был связан с владельцем файла. После всего этого все волшебным образом работает! Я очень надеюсь, что к концу этой книги я начну понимать хотя бы кое-что из этого :( В любом случае, спасибо

0 голосов
/ 27 октября 2011

Вы не реализовали метод получения для employees.Предполагая, что вы намерены использовать Key-Value Coding для изменения массива, либо напрямую, либо через Bindings, вам нужно реализовать как getter, так и setter для того, чтобы этот объект был KVC-совместимым для этого свойства.

Как только вывыполнить минимальные требования для соответствия KVC, тогда KVC распознает свойство и использует его средства доступа, включая любые реализуемые вами средства доступа к массиву.

Если вы загляните в консоль отладчика, вы можете обнаружить, что KVC уже говорит вам об этомв форме «<Some object> is not KVC-compliant for <some property>» исключений.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...