, Это очень хорошее предложение, и если у вас нет конкретной причины для непосредственного наблюдения за объектом, вы должны принять его. (Одним из преимуществ является то, что вы можете использовать привязки для подключения представлений к новому контроллеру массива.)

аюсь заставить наблюдение значения ключа работать для NSMutableArray. Ниже приведен файл .h для MyObservee, наблюдаемого класса:

@interface MyObservee : NSObject {
    @private int someValue;
    @private NSMutableArray *someArray;
}

@property (readwrite,assign) int someValue;
- (NSMutableArray *)someArray;
@end

Класс MyObserver реализует наблюденийValueForKeyPath: ofObject: change: context :. Вот как я добавляю наблюдателя:

MyObservee *moe = [[MyObservee alloc] init];
MyObserver *mobs = [[MyObserver alloc] init];

[moe addObserver:mobs 
      forKeyPath:@"someArray" 
         options:(NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld) 
         context:NULL];

[moe.someArray addObject:@"hi there"];

Почему сообщение addObject: не срабатывает как изменение пути к ключу someArray? У меня есть чувство, что я здесь чего-то не понимаю.

Ответы на вопрос(3)

Решение Вопроса

как определено вРуководство по программированию KVC, Затем вы должны использовать эти средства доступа для доступа к массиву, и запуск KVO будет работать. Вы также можете позвонить-mutableArrayValueForKey: и использовать этот массив для addObject: и так далее, и он, в свою очередь, будет вызывать методы доступа, и также будет запускаться KVO. Есть также установленные средства доступа для использования в NSSets, см.Вот а такжеВот.

Пример:

@interface MyClass : NSObject
{
    NSMutableArray *_orders;
}

@property(retain) NSMutableArray *orders;

- (NSUInteger)countOfOrders;
- (id)objectInOrdersAtIndex:(NSUInteger)index;
- (void)insertObject:(id)obj inOrdersAtIndex:(NSUInteger)index;
- (void)removeObjectFromOrdersAtIndex:(NSUInteger)index;
- (void)replaceObjectInOrdersAtIndex:(NSUInteger)index withObject:(id)obj;


@end
 Peter Hosey25 янв. 2009 г., 11:16
Джейсон Коко: Да, как правило, следует использовать NSArrayController, но это не решает проблему изменения базовой модели и получения уведомлений KVO.
 Jason Coco25 янв. 2009 г., 07:48
или ... вы можете просто использовать NSArrayController ;-)

приватно, когда вы позволяете другим объектам обрабатывать это.

Как сказал s-bug, вы должны реализовать средства доступа и использоватьmutableArrayValueForKey: мутировать собственность. Добавлю чтоВы не должны подвергать этот закрытый массив вообще-твойsomeArray Метод должен вернуть неизменяемую копию массива.

Кроме того, я обращаю ваше внимание на комментарий Джейсона Коко на ответ s-bug. Перефразируя его, вы, вероятно, должны использоватьNSArrayController в качестве дополнительного шага разделения междуmyObservee а такжеmyObserver, Это очень хорошее предложение, и если у вас нет конкретной причины для непосредственного наблюдения за объектом, вы должны принять его. (Одним из преимуществ является то, что вы можете использовать привязки для подключения представлений к новому контроллеру массива.)

классы NSArray соответствуют стандартам KVO. Они соответствуют KVC, но вы не можете наблюдать их непосредственно, как вы пытаетесь сделать здесь. Самый простой способ получить эту функциональность - использовать NSArrayController. Контроллер NSArray совместим с KVO и предупредит вас, когда элементы будут добавлены или удалены. В вашем примере ваш наблюдатель будет уведомлен, если вы на самом делеизменено сам массив. Например, если вы сделали что-то вроде этого:

[moe setSomeArray:[NSMutableArray array]];

Что, вероятно, совсем не то, что вы хотели :). Кроме того, NSDictionary на самом деле совместим с KVO, поэтому вы можете использовать его, если захотите. Или вы можете написать подкласс обертки NSMutableArray, который просто создает реальный изменяемый массив в качестве своего резервного хранилища, но просто пересылает ему все сообщения, кромеaddObject а такжеremoveObject которую вы можете переопределить, чтобы вызвать уведомления.

Ваш ответ на вопрос