КВО с NSMutableArray - PullRequest
       0

КВО с NSMutableArray

3 голосов
/ 08 августа 2011

У меня есть свойство NSMutableArray в моем AppDelegate, называемое блоками. Я хотел бы наблюдать, когда объект добавляется в этот массив. Я читал другие посты, но не могу понять, почему это не работает.

В моем классе делегата приложения я реализую

- (void)insertObject:(id)obj inBlocksAtIndex:(NSInteger)index
{
    [blocks insertObject:obj atIndex:index];
}

В методе init моего контроллера представления я добавляю наблюдателя к моей ссылке AppDelegate.

boardModel = [[UIApplication sharedApplication] delegate];
[boardModel addObserver:self forKeyPath:@"blocks" options:0 context:NULL];

В моем методе viewDidLoad контроллера представления я пытаюсь вызвать средство доступа к индексированному массиву KVO, которое я реализовал ранее,

[boardModel insertObject:[[Block alloc] init] inBlocksAtIndex:0];

Затем я реализую свой метод наблюдать за ValveForKeyPath:

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
    if ([keyPath isEqualToString:@"blocks"])
    {
        NSLog(@"ADDED");
    }
}

Я попытался добавить оператор NSLog перед оператором if в наблюдаемом значенииForKeyPath, и кажется, что он никогда не вызывается.

Я также пробовал NSLogging [[boardModel blocks] count], и он говорит, что счетчик равен 1 (объект добавляется).

Должно быть, я что-то упустил.

Ответы [ 5 ]

12 голосов
/ 20 августа 2011

Загвоздка в том, что NSArray s не уважают KVO, поэтому наблюдение за количеством ключевых путей не будет работать.

Если это MacOSX, используйте NSArrayController.в противном случае реализуйте класс-оболочку для массива, который запускает вызовы KVO при добавлении / удалении содержимого массива и передает все остальные вызовы.

1 голос
/ 25 ноября 2013

Вы пробовали

   - (void)insertObject:(id)obj inBlocksAtIndex:(NSInteger)index
    {
        [[self mutableArrayValueForKey:@"blocks"] insertObject:obj atIndex:index];
     }
0 голосов
/ 27 апреля 2017

Дело не в том, что NSMutableArray не является KVO-совместимым в некоторых отношениях, а в том, что все KVO-совместимые свойства должны быть объектами NSO. «count» - это NSUInteger; Вы не можете наблюдать это свойство напрямую. Если бы это был объект NSNumber, вы могли бы.

Из заголовочного файла NSArray:

@interface NSArray<__covariant ObjectType> : NSObject <NSCopying, NSMutableCopying, NSSecureCoding, NSFastEnumeration>

@property (readonly) NSUInteger count;

Почему ответ был принят, кстати? Ясно, что ответчик не проверял свой ответ.

0 голосов
/ 16 марта 2014

Я только что открыл очень маленькую библиотеку Objective-C, которая добавляет делегата в NSMutableArray. Это может помочь вам достичь того, что вы пытались сделать. Проверьте FCMutableArray на GitHub

0 голосов
/ 08 августа 2011

Вы наблюдаете свойство blocks делегата приложения, а не сам массив blocks. Надеемся, что следующий пример прояснит разницу:

// This will fire KVO as you're changing the app delegate's `blocks` property.
appDelegate.blocks = [NSMutableArray array];

// This will not fire KVO as the app delegate's `blocks` property still points
// to the same object; from the app delegate's perspective, nothing's happened.
[appDelegate.blocks addObject:@"Object"];

Если вы хотите получать уведомления об изменении содержимого массива blocks, обратите внимание на свойство самого массива - что-то вроде count. Обновление вашего кода:

[boardModel.blocks addObserver:self forKeyPath:@"count" options:0 context:NULL];
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...