18

誰かが ReactiveCocoa 抽象化を使用して次のようなことを達成する 1 行の例を提供できますか?

// pseudo-code
NSMutableArray *array = @[[] mutableCopy];
RACSignal *newValue = RACAbleWithStart(array); // get whole array or maybe just added/removed element on push/pop

[newValue subscribeNext:^(NSArray *x) {
  // x is whole array
}]

[newValue subscribeNext:^(id x) {
  // x is new value
}]

[newValue subscribeNext:^(id x) {
  // x is removed value
}]

Mantle https://github.com/ReactiveCocoa/ReactiveCocoa/pull/130を優先して NSArray の一部の拡張機能が削除されたようですが、NSArray 操作の簡単な例はまだ見つかりません。

4

2 に答える 2

15

配列の変更を観察することはできません。ReactiveCocoa はキー値観測を使用します。名前が示すように、キー属性 (辞書メンバー、プロパティなど) の変更のみを監視します。

あなたができることは、変更の配列プロパティを観察することです:

@interface Blah : NSObject
@property (copy, readonly) NSArray *arrayProperty;
@end

// later...
Blah *blah = [Blah new];
[RACObserve(blah, arrayProperty) subscribeNext:^(NSArray *wholeArray){}];

挿入/削除されたオブジェクトを知りたい場合は、2 つのオプションがあります。各配列を保存し、それぞれを前の配列と比較することで解決できます。これは最も単純ですが、非常に大きな配列ではパフォーマンスが低下します。私の知る限り、ReactiveCocoaにはこれを行うための組み込み操作がありません。

または、KVO コレクション アクセサーを実装し、配列への変更がmutableArrayValueForKey:. これにより、変更が行われるたびに新しい配列が作成されるのを回避し、また、によって返されるプロキシ配列に加えられた変更をオブザーバーに通知しmutableArrayValueForKey:ます。

ReactiveCocoa を使用して変更情報を観察することは、もう少し複雑です。

RACSignal *changeSignal = [blah rac_valuesAndChangesForKeyPath:@keypath(blah, arrayProperty) options: NSKeyValueObservingOptionNew| NSKeyValueObservingOptionOld observer:nil];
[changeSignal subscribeNext:^(RACTuple *x){
    NSArray *wholeArray = x.first;
    NSDictionary *changeDictionary = x.second;
}];

変更ディクショナリは、配列に加えられた変更の種類、挿入/削除されたオブジェクト、および挿入/削除されたオブジェクトのインデックスを示します。

https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Protocols/NSKeyValueObserving_Protocol/Reference/Reference.htmlで文書化されています。

于 2013-09-13T13:01:55.477 に答える
2

クリスのソリューションの迅速な同等物:

let signal = self.object.rac_valuesAndChangesForKeyPath("property", options:      NSKeyValueObservingOptions.New | NSKeyValueObservingOptions.Old, observer:self.object)
signal.subscribeNext { (object) -> Void in
   if let tuple = object as? RACTuple {
        var wholeArray = tuple.first as? NSArray
        var changeDictionary = tuple.second as? NSDictionary
    }
}

また、KVO に準拠した方法でコンテンツ プロパティを変更してください。

// This is wrong and wont send values to RAC signals
[self.contents addObject:object];

// This is correct and will send values to RAC signals
NSMutableArray *contents = [account mutableArrayValueForKey:@keypath(self, contents)];
[contents addObject:object];

編集: 物事をより明確にするために、プロパティの代わりに配列の名前を入れてください。例えば:

lazy var widgets:NSMutableArray = NSMutableArray()
let signal = self.rac_valuesAndChangesForKeyPath("widgets", options:      NSKeyValueObservingOptions.New | NSKeyValueObservingOptions.Old, observer:self)
于 2014-11-19T08:51:48.263 に答える