NSMutableArrayでのオブジェクト追加/削除をKVOで拾いたい場合


結果だけ。
KVOで監視しているKeyPath(NSMutableArray)を、"mutableArrayValueForKey:"で一度ラッピングしてやると、addObject/removeXXObjectに反応するようになる。


```objc
//
//  ViewController.m
//  KVOMutableArray
//
//  Created by Takafumi Tamura on 2013/04/07.
//  Copyright (c) 2013年 田村 孝文. All rights reserved.
//

#import "ViewController.h"

@interface ViewController ()
@property(nonatomic,strong)NSMutableArray *array;
@property(nonatomic,strong)NSMutableArray *proxyArray;
@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    [self addObserver:self
           forKeyPath:@"array"
              options:  NSKeyValueObservingOptionNew |
                        NSKeyValueObservingOptionOld
              context:nil];
	// Do any additional setup after loading the view, typically from a nib.
    self.array = [[NSMutableArray alloc]init];  // (self の array に値が入るから）反応する
    [self.array addObject:@"fuga"]; // これは反応しない。
    self.proxyArray = [self mutableArrayValueForKey:@"array"];
    [self.proxyArray addObject:@"hoge1"]; // 反応する
    [self.proxyArray addObject:@"hoge2"]; // 反応する
    [self.proxyArray addObject:@"hoge3"]; // 反応する
    [self.proxyArray removeLastObject]; // 反応する
    [self.proxyArray removeAllObjects]; // 反応する,fugaの削除にも反応。
    
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

-(void)observeValueForKeyPath:(NSString *)keyPath
                     ofObject:(id)object
                       change:(NSDictionary *)change
                      context:(void *)context
{
    NSLog(@"keyPath=%@ object=%@ change:%@ context:%@",keyPath, object,change,context);
}

@end

```

```:NSLogの結果
2013-04-07 21:55:02.490 KVOMutableArray[11816:c07] keyPath=array object=<ViewController: 0x7559e30> change:{
    kind = 1;
    new =     (
    );
    old = "<null>";
} context:(null)
2013-04-07 21:55:09.090 KVOMutableArray[11816:c07] keyPath=array object=<ViewController: 0x7559e30> change:{
    indexes = "<NSIndexSet: 0x714dd70>[number of indexes: 1 (in 1 ranges), indexes: (1)]";
    kind = 2;
    new =     (
        hoge1
    );
} context:(null)
2013-04-07 21:55:11.090 KVOMutableArray[11816:c07] keyPath=array object=<ViewController: 0x7559e30> change:{
    indexes = "<NSIndexSet: 0x714dd70>[number of indexes: 1 (in 1 ranges), indexes: (2)]";
    kind = 2;
    new =     (
        hoge2
    );
} context:(null)
2013-04-07 21:55:13.571 KVOMutableArray[11816:c07] keyPath=array object=<ViewController: 0x7559e30> change:{
    indexes = "<NSIndexSet: 0x75168c0>[number of indexes: 1 (in 1 ranges), indexes: (3)]";
    kind = 2;
    new =     (
        hoge3
    );
} context:(null)
2013-04-07 21:55:15.659 KVOMutableArray[11816:c07] keyPath=array object=<ViewController: 0x7559e30> change:{
    indexes = "<NSIndexSet: 0x714dd70>[number of indexes: 1 (in 1 ranges), indexes: (3)]";
    kind = 3;
    old =     (
        hoge3
    );
} context:(null)
2013-04-07 21:55:25.640 KVOMutableArray[11816:c07] keyPath=array object=<ViewController: 0x7559e30> change:{
    indexes = "<NSIndexSet: 0x755df40>[number of indexes: 1 (in 1 ranges), indexes: (2)]";
    kind = 3;
    old =     (
        hoge2
    );
} context:(null)
2013-04-07 21:55:30.838 KVOMutableArray[11816:c07] keyPath=array object=<ViewController: 0x7559e30> change:{
    indexes = "<NSIndexSet: 0x755df40>[number of indexes: 1 (in 1 ranges), indexes: (1)]";
    kind = 3;
    old =     (
        hoge1
    );
} context:(null)
2013-04-07 21:55:37.397 KVOMutableArray[11816:c07] keyPath=array object=<ViewController: 0x7559e30> change:{
    indexes = "<NSIndexSet: 0x755df40>[number of indexes: 1 (in 1 ranges), indexes: (0)]";
    kind = 3;
    old =     (
        fuga
    );
} context:(null)

```