Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 542 lines (423 sloc) 14.612 kb
0b05b4b Add KVC+KVO support for "To Many" keys (i.e. Arrays).
Ross Boucher authored
1 /*
2 * CPArray+KVO.j
3 * Foundation
4 *
5 * Created by Ross Boucher.
6 * Copyright 2008, 280 North, Inc.
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22
23 @import "CPArray.j"
9e62fdc added missing CPNull imports
Tom Robinson authored
24 @import "CPNull.j"
e2ead56 @aparajita Collection KVC fixes, nextObject correctness
aparajita authored
25 @import "_CPCollectionKVCOperators.j"
0b05b4b Add KVC+KVO support for "To Many" keys (i.e. Arrays).
Ross Boucher authored
26
b98f0b1 @stevegeek Apply style rules to Foundation
stevegeek authored
27
0b05b4b Add KVC+KVO support for "To Many" keys (i.e. Arrays).
Ross Boucher authored
28 @implementation CPObject (CPArrayKVO)
29
30 - (id)mutableArrayValueForKey:(id)aKey
31 {
923d7c6 @aljungberg Fixed an accidental global.
aljungberg authored
32 return [[_CPKVCArray alloc] initWithKey:aKey forProxyObject:self];
0b05b4b Add KVC+KVO support for "To Many" keys (i.e. Arrays).
Ross Boucher authored
33 }
34
35 - (id)mutableArrayValueForKeyPath:(id)aKeyPath
36 {
37 var dotIndex = aKeyPath.indexOf(".");
b98f0b1 @stevegeek Apply style rules to Foundation
stevegeek authored
38
0b05b4b Add KVC+KVO support for "To Many" keys (i.e. Arrays).
Ross Boucher authored
39 if (dotIndex < 0)
40 return [self mutableArrayValueForKey:aKeyPath];
41
42 var firstPart = aKeyPath.substring(0, dotIndex),
b98f0b1 @stevegeek Apply style rules to Foundation
stevegeek authored
43 lastPart = aKeyPath.substring(dotIndex + 1);
0b05b4b Add KVC+KVO support for "To Many" keys (i.e. Arrays).
Ross Boucher authored
44
9c7b347 @dasto fixed bug in "mutableArrayValueForKeyPath:" in CPArray+KVO.j which wa…
dasto authored
45 return [[self valueForKeyPath:firstPart] mutableArrayValueForKeyPath:lastPart];
0b05b4b Add KVC+KVO support for "To Many" keys (i.e. Arrays).
Ross Boucher authored
46 }
47
48 @end
49
b0feeb3 @dasto improved cocoa compatibility by _CPKVCArray-proxy inheriting from CPM…
dasto authored
50 @implementation _CPKVCArray : CPMutableArray
0b05b4b Add KVC+KVO support for "To Many" keys (i.e. Arrays).
Ross Boucher authored
51 {
52 id _proxyObject;
53 id _key;
b98f0b1 @stevegeek Apply style rules to Foundation
stevegeek authored
54
0b05b4b Add KVC+KVO support for "To Many" keys (i.e. Arrays).
Ross Boucher authored
55 SEL _insertSEL;
56 Function _insert;
b98f0b1 @stevegeek Apply style rules to Foundation
stevegeek authored
57
0b05b4b Add KVC+KVO support for "To Many" keys (i.e. Arrays).
Ross Boucher authored
58 SEL _removeSEL;
59 Function _remove;
b98f0b1 @stevegeek Apply style rules to Foundation
stevegeek authored
60
0b05b4b Add KVC+KVO support for "To Many" keys (i.e. Arrays).
Ross Boucher authored
61 SEL _replaceSEL;
62 Function _replace;
b98f0b1 @stevegeek Apply style rules to Foundation
stevegeek authored
63
546c95b @cacaodev Fixed typos in CPArray+KVO ; added suport for *objects:atIndexes:
cacaodev authored
64 SEL _insertManySEL;
65 Function _insertMany;
b98f0b1 @stevegeek Apply style rules to Foundation
stevegeek authored
66
546c95b @cacaodev Fixed typos in CPArray+KVO ; added suport for *objects:atIndexes:
cacaodev authored
67 SEL _removeManySEL;
68 Function _removeMany;
b98f0b1 @stevegeek Apply style rules to Foundation
stevegeek authored
69
546c95b @cacaodev Fixed typos in CPArray+KVO ; added suport for *objects:atIndexes:
cacaodev authored
70 SEL _replaceManySEL;
71 Function _replaceMany;
b98f0b1 @stevegeek Apply style rules to Foundation
stevegeek authored
72
0b05b4b Add KVC+KVO support for "To Many" keys (i.e. Arrays).
Ross Boucher authored
73 SEL _objectAtIndexSEL;
74 Function _objectAtIndex;
b98f0b1 @stevegeek Apply style rules to Foundation
stevegeek authored
75
b0feeb3 @dasto improved cocoa compatibility by _CPKVCArray-proxy inheriting from CPM…
dasto authored
76 SEL _objectsAtIndexesSEL;
77 Function _objectsAtIndexes;
78
0b05b4b Add KVC+KVO support for "To Many" keys (i.e. Arrays).
Ross Boucher authored
79 SEL _countSEL;
80 Function _count;
b98f0b1 @stevegeek Apply style rules to Foundation
stevegeek authored
81
0b05b4b Add KVC+KVO support for "To Many" keys (i.e. Arrays).
Ross Boucher authored
82 SEL _accessSEL;
83 Function _access;
b98f0b1 @stevegeek Apply style rules to Foundation
stevegeek authored
84
0b05b4b Add KVC+KVO support for "To Many" keys (i.e. Arrays).
Ross Boucher authored
85 SEL _setSEL;
86 Function _set;
87 }
88
89 + (id)alloc
90 {
3a35ab4 @tolmasky Fixed failing KVO tests.
tolmasky authored
91 var array = [];
92
93 array.isa = self;
94
0b05b4b Add KVC+KVO support for "To Many" keys (i.e. Arrays).
Ross Boucher authored
95 var ivars = class_copyIvarList(self),
96 count = ivars.length;
97
98 while (count--)
3a35ab4 @tolmasky Fixed failing KVO tests.
tolmasky authored
99 array[ivar_getName(ivars[count])] = nil;
0b05b4b Add KVC+KVO support for "To Many" keys (i.e. Arrays).
Ross Boucher authored
100
3a35ab4 @tolmasky Fixed failing KVO tests.
tolmasky authored
101 return array;
0b05b4b Add KVC+KVO support for "To Many" keys (i.e. Arrays).
Ross Boucher authored
102 }
103
b98f0b1 @stevegeek Apply style rules to Foundation
stevegeek authored
104 - (id)initWithKey:(id)aKey forProxyObject:(id)anObject
0b05b4b Add KVC+KVO support for "To Many" keys (i.e. Arrays).
Ross Boucher authored
105 {
106 self = [super init];
107
108 _key = aKey;
109 _proxyObject = anObject;
b98f0b1 @stevegeek Apply style rules to Foundation
stevegeek authored
110
0b05b4b Add KVC+KVO support for "To Many" keys (i.e. Arrays).
Ross Boucher authored
111 var capitalizedKey = _key.charAt(0).toUpperCase() + _key.substring(1);
b98f0b1 @stevegeek Apply style rules to Foundation
stevegeek authored
112
b381fe6 @aljungberg Cleanup.
aljungberg authored
113 _insertSEL = sel_getName(@"insertObject:in" + capitalizedKey + "AtIndex:");
546c95b @cacaodev Fixed typos in CPArray+KVO ; added suport for *objects:atIndexes:
cacaodev authored
114 if ([_proxyObject respondsToSelector:_insertSEL])
115 _insert = [_proxyObject methodForSelector:_insertSEL];
0b05b4b Add KVC+KVO support for "To Many" keys (i.e. Arrays).
Ross Boucher authored
116
b381fe6 @aljungberg Cleanup.
aljungberg authored
117 _removeSEL = sel_getName(@"removeObjectFrom" + capitalizedKey + "AtIndex:");
546c95b @cacaodev Fixed typos in CPArray+KVO ; added suport for *objects:atIndexes:
cacaodev authored
118 if ([_proxyObject respondsToSelector:_removeSEL])
119 _remove = [_proxyObject methodForSelector:_removeSEL];
b98f0b1 @stevegeek Apply style rules to Foundation
stevegeek authored
120
b381fe6 @aljungberg Cleanup.
aljungberg authored
121 _replaceSEL = sel_getName(@"replaceObjectIn" + capitalizedKey + "AtIndex:withObject:");
546c95b @cacaodev Fixed typos in CPArray+KVO ; added suport for *objects:atIndexes:
cacaodev authored
122 if ([_proxyObject respondsToSelector:_replaceSEL])
123 _replace = [_proxyObject methodForSelector:_replaceSEL];
124
b381fe6 @aljungberg Cleanup.
aljungberg authored
125 _insertManySEL = sel_getName(@"insert" + capitalizedKey + ":atIndexes:");
546c95b @cacaodev Fixed typos in CPArray+KVO ; added suport for *objects:atIndexes:
cacaodev authored
126 if ([_proxyObject respondsToSelector:_insertManySEL])
b21eab1 @klaaspieter Improved KVC mutable indexed accessors
klaaspieter authored
127 _insertMany = [_proxyObject methodForSelector:_insertManySEL];
546c95b @cacaodev Fixed typos in CPArray+KVO ; added suport for *objects:atIndexes:
cacaodev authored
128
b381fe6 @aljungberg Cleanup.
aljungberg authored
129 _removeManySEL = sel_getName(@"remove" + capitalizedKey + "AtIndexes:");
546c95b @cacaodev Fixed typos in CPArray+KVO ; added suport for *objects:atIndexes:
cacaodev authored
130 if ([_proxyObject respondsToSelector:_removeManySEL])
249a63a @klaaspieter don't use remove method for removeMany selector
klaaspieter authored
131 _removeMany = [_proxyObject methodForSelector:_removeManySEL];
b98f0b1 @stevegeek Apply style rules to Foundation
stevegeek authored
132
b381fe6 @aljungberg Cleanup.
aljungberg authored
133 _replaceManySEL = sel_getName(@"replace" + capitalizedKey + "AtIndexes:with" + capitalizedKey + ":");
546c95b @cacaodev Fixed typos in CPArray+KVO ; added suport for *objects:atIndexes:
cacaodev authored
134 if ([_proxyObject respondsToSelector:_replaceManySEL])
5b00f7f @klaaspieter improve _CPKVCArray
klaaspieter authored
135 _replaceMany = [_proxyObject methodForSelector:_replaceManySEL];
b98f0b1 @stevegeek Apply style rules to Foundation
stevegeek authored
136
b381fe6 @aljungberg Cleanup.
aljungberg authored
137 _objectAtIndexSEL = sel_getName(@"objectIn" + capitalizedKey + "AtIndex:");
546c95b @cacaodev Fixed typos in CPArray+KVO ; added suport for *objects:atIndexes:
cacaodev authored
138 if ([_proxyObject respondsToSelector:_objectAtIndexSEL])
139 _objectAtIndex = [_proxyObject methodForSelector:_objectAtIndexSEL];
0b05b4b Add KVC+KVO support for "To Many" keys (i.e. Arrays).
Ross Boucher authored
140
b381fe6 @aljungberg Cleanup.
aljungberg authored
141 _objectsAtIndexesSEL = sel_getName(_key + "AtIndexes:");
b0feeb3 @dasto improved cocoa compatibility by _CPKVCArray-proxy inheriting from CPM…
dasto authored
142 if ([_proxyObject respondsToSelector:_objectsAtIndexesSEL])
143 _objectsAtIndexes = [_proxyObject methodForSelector:_objectsAtIndexesSEL];
144
b381fe6 @aljungberg Cleanup.
aljungberg authored
145 _countSEL = sel_getName(@"countOf" + capitalizedKey);
546c95b @cacaodev Fixed typos in CPArray+KVO ; added suport for *objects:atIndexes:
cacaodev authored
146 if ([_proxyObject respondsToSelector:_countSEL])
147 _count = [_proxyObject methodForSelector:_countSEL];
0b05b4b Add KVC+KVO support for "To Many" keys (i.e. Arrays).
Ross Boucher authored
148
149 _accessSEL = sel_getName(_key);
546c95b @cacaodev Fixed typos in CPArray+KVO ; added suport for *objects:atIndexes:
cacaodev authored
150 if ([_proxyObject respondsToSelector:_accessSEL])
151 _access = [_proxyObject methodForSelector:_accessSEL];
0b05b4b Add KVC+KVO support for "To Many" keys (i.e. Arrays).
Ross Boucher authored
152
b381fe6 @aljungberg Cleanup.
aljungberg authored
153 _setSEL = sel_getName(@"set" + capitalizedKey + ":");
546c95b @cacaodev Fixed typos in CPArray+KVO ; added suport for *objects:atIndexes:
cacaodev authored
154 if ([_proxyObject respondsToSelector:_setSEL])
155 _set = [_proxyObject methodForSelector:_setSEL];
0b05b4b Add KVC+KVO support for "To Many" keys (i.e. Arrays).
Ross Boucher authored
156
157 return self;
158 }
159
160 - (id)copy
161 {
b98f0b1 @stevegeek Apply style rules to Foundation
stevegeek authored
162 var i = 0,
163 theCopy = [],
0b05b4b Add KVC+KVO support for "To Many" keys (i.e. Arrays).
Ross Boucher authored
164 count = [self count];
165
b98f0b1 @stevegeek Apply style rules to Foundation
stevegeek authored
166 for (; i < count; i++)
0b05b4b Add KVC+KVO support for "To Many" keys (i.e. Arrays).
Ross Boucher authored
167 [theCopy addObject:[self objectAtIndex:i]];
168
169 return theCopy;
170 }
171
b98f0b1 @stevegeek Apply style rules to Foundation
stevegeek authored
172 - (id)_representedObject
0b05b4b Add KVC+KVO support for "To Many" keys (i.e. Arrays).
Ross Boucher authored
173 {
174 if (_access)
175 return _access(_proxyObject, _accessSEL);
176
177 return [_proxyObject valueForKey:_key];
178 }
179
b98f0b1 @stevegeek Apply style rules to Foundation
stevegeek authored
180 - (void)_setRepresentedObject:(id)anObject
0b05b4b Add KVC+KVO support for "To Many" keys (i.e. Arrays).
Ross Boucher authored
181 {
182 if (_set)
183 return _set(_proxyObject, _setSEL, anObject);
184
185 [_proxyObject setValue:anObject forKey:_key];
186 }
187
188 - (unsigned)count
189 {
190 if (_count)
191 return _count(_proxyObject, _countSEL);
192
193 return [[self _representedObject] count];
194 }
195
75fdfb5 @tolmasky Improved observable arrays to support indexOfObject:, indexOfObjectId…
tolmasky authored
196 - (int)indexOfObject:(CPObject)anObject inRange:(CPRange)aRange
197 {
198 var index = aRange.location,
199 count = aRange.length,
200 shouldIsEqual = !!anObject.isa;
201
202 for (; index < count; ++index)
203 {
204 var object = [self objectAtIndex:index];
205
206 if (anObject === object || shouldIsEqual && !!object.isa && [anObject isEqual:object])
207 return index;
208 }
209
210 return CPNotFound;
211 }
212
213 - (int)indexOfObject:(CPObject)anObject
214 {
e329633 @cacaodev _CPKVCArray -indexOfObject: typo
cacaodev authored
215 return [self indexOfObject:anObject inRange:CPMakeRange(0, [self count])];
75fdfb5 @tolmasky Improved observable arrays to support indexOfObject:, indexOfObjectId…
tolmasky authored
216 }
217
218 - (int)indexOfObjectIdenticalTo:(CPObject)anObject inRange:(CPRange)aRange
219 {
220 var index = aRange.location,
221 count = aRange.length;
222
223 for (; index < count; ++index)
224 if (anObject === [self objectAtIndex:index])
225 return index;
226
227 return CPNotFound;
228 }
229
230 - (int)indexOfObjectIdenticalTo:(CPObject)anObject
231 {
232 return [self indexOfObjectIdenticalTo:anObject inRange:CPMakeRange(0, [self count])];
233 }
234
0b05b4b Add KVC+KVO support for "To Many" keys (i.e. Arrays).
Ross Boucher authored
235 - (id)objectAtIndex:(unsigned)anIndex
236 {
5b00f7f @klaaspieter improve _CPKVCArray
klaaspieter authored
237 return [[self objectsAtIndexes:[CPIndexSet indexSetWithIndex:anIndex]] firstObject];
238 }
239
240 - (CPArray)objectsAtIndexes:(CPIndexSet)theIndexes
241 {
242 if (_objectsAtIndexes)
243 return _objectsAtIndexes(_proxyObject, _objectsAtIndexesSEL, theIndexes);
e2ead56 @aparajita Collection KVC fixes, nextObject correctness
aparajita authored
244
b98f0b1 @stevegeek Apply style rules to Foundation
stevegeek authored
245 if (_objectAtIndex)
5b00f7f @klaaspieter improve _CPKVCArray
klaaspieter authored
246 {
247 var index = CPNotFound,
248 objects = [];
249
250 while ((index = [theIndexes indexGreaterThanIndex:index]) !== CPNotFound)
251 objects.push(_objectAtIndex(_proxyObject, _objectAtIndexSEL, index));
252
253 return objects;
254 }
0b05b4b Add KVC+KVO support for "To Many" keys (i.e. Arrays).
Ross Boucher authored
255
5b00f7f @klaaspieter improve _CPKVCArray
klaaspieter authored
256 return [[self _representedObject] objectsAtIndexes:theIndexes];
0b05b4b Add KVC+KVO support for "To Many" keys (i.e. Arrays).
Ross Boucher authored
257 }
258
259 - (void)addObject:(id)anObject
260 {
b21eab1 @klaaspieter Improved KVC mutable indexed accessors
klaaspieter authored
261 [self insertObject:anObject atIndex:[self count]];
0b05b4b Add KVC+KVO support for "To Many" keys (i.e. Arrays).
Ross Boucher authored
262 }
263
75fdfb5 @tolmasky Improved observable arrays to support indexOfObject:, indexOfObjectId…
tolmasky authored
264 - (void)addObjectsFromArray:(CPArray)anArray
265 {
266 var index = 0,
267 count = [anArray count];
268
213fde0 @klaaspieter fix CPArray+KVO addObjects inserting objects at beginning of array on…
klaaspieter authored
269 [self insertObjects:anArray atIndexes:[CPIndexSet indexSetWithIndexesInRange:CPMakeRange([self count], count)]];
75fdfb5 @tolmasky Improved observable arrays to support indexOfObject:, indexOfObjectId…
tolmasky authored
270 }
271
0b05b4b Add KVC+KVO support for "To Many" keys (i.e. Arrays).
Ross Boucher authored
272 - (void)insertObject:(id)anObject atIndex:(unsigned)anIndex
273 {
b21eab1 @klaaspieter Improved KVC mutable indexed accessors
klaaspieter authored
274 [self insertObjects:[anObject] atIndexes:[CPIndexSet indexSetWithIndex:anIndex]];
275 }
276
277 - (void)insertObjects:(CPArray)theObjects atIndexes:(CPIndexSet)theIndexes
278 {
279 if (_insertMany)
280 _insertMany(_proxyObject, _insertManySEL, theObjects, theIndexes);
281 else if (_insert)
282 {
283 var indexesArray = [];
284 [theIndexes getIndexes:indexesArray maxCount:-1 inIndexRange:nil];
0b05b4b Add KVC+KVO support for "To Many" keys (i.e. Arrays).
Ross Boucher authored
285
b21eab1 @klaaspieter Improved KVC mutable indexed accessors
klaaspieter authored
286 for (var index = 0; index < [indexesArray count]; index++)
287 {
288 var objectIndex = [indexesArray objectAtIndex:index],
289 object = [theObjects objectAtIndex:index];
b98f0b1 @stevegeek Apply style rules to Foundation
stevegeek authored
290
b21eab1 @klaaspieter Improved KVC mutable indexed accessors
klaaspieter authored
291 _insert(_proxyObject, _insertSEL, object, objectIndex);
292 }
293 }
294 else
295 {
296 var target = [[self _representedObject] copy];
297
298 [target insertObjects:theObjects atIndexes:theIndexes];
299 [self _setRepresentedObject:target];
300 }
0b05b4b Add KVC+KVO support for "To Many" keys (i.e. Arrays).
Ross Boucher authored
301 }
302
bc0fa6a @klaaspieter made removeObject on _CPKVCArray work properly
klaaspieter authored
303 - (void)removeObject:(id)anObject
304 {
305 [self removeObject:anObject inRange:CPMakeRange(0, [self count])];
306 }
307
e99e266 @klaaspieter more fixes and tests for _CPKVCArray
klaaspieter authored
308 - (void)removeObjectsInArray:(CPArray)theObjects
309 {
310 if (_removeMany)
311 {
312 var indexes = [CPIndexSet indexSet],
313 index = [theObjects count];
314
315 while (index--)
316 [indexes addIndex:[self indexOfObject:[theObjects objectAtIndex:index]]];
317
318 _removeMany(_proxyObject, _removeManySEL, indexes);
319 }
320 else if (_remove)
321 {
322 var index = [theObjects count];
323 while (index--)
324 _remove(_proxyObject, _removeSEL, [self indexOfObject:[theObjects objectAtIndex:index]]);
325 }
326 else
327 {
328 var target = [[self _representedObject] copy];
329 [target removeObjectsInArray:theObjects];
330 [self _setRepresentedObject:target];
331 }
332 }
333
5b00f7f @klaaspieter improve _CPKVCArray
klaaspieter authored
334 - (void)removeObject:(id)theObject inRange:(CPRange)theRange
335 {
336 if (_remove)
337 _remove(_proxyObject, _removeSEL, [self indexOfObject:theObject inRange:theRange]);
338 else if (_removeMany)
339 {
340 var index = [self indexOfObject:theObject inRange:theRange];
341 _removeMany(_proxyObject, _removeManySEL, [CPIndexSet indexSetWithIndex:index]);
342 }
343 else
344 {
345 var index;
346
347 while ((index = [self indexOfObject:theObject inRange:theRange]) !== CPNotFound)
348 {
349 [self removeObjectAtIndex:index];
350 theRange = CPIntersectionRange(CPMakeRange(index, length - index), theRange);
351 }
352 }
353 }
354
0b05b4b Add KVC+KVO support for "To Many" keys (i.e. Arrays).
Ross Boucher authored
355 - (void)removeLastObject
356 {
e99e266 @klaaspieter more fixes and tests for _CPKVCArray
klaaspieter authored
357 [self removeObjectsAtIndexes:[CPIndexSet indexSetWithIndex:[self count] - 1]];
0b05b4b Add KVC+KVO support for "To Many" keys (i.e. Arrays).
Ross Boucher authored
358 }
359
360 - (void)removeObjectAtIndex:(unsigned)anIndex
361 {
5b00f7f @klaaspieter improve _CPKVCArray
klaaspieter authored
362 [self removeObjectsAtIndexes:[CPIndexSet indexSetWithIndex:anIndex]];
363 }
0b05b4b Add KVC+KVO support for "To Many" keys (i.e. Arrays).
Ross Boucher authored
364
5b00f7f @klaaspieter improve _CPKVCArray
klaaspieter authored
365 - (void)removeObjectsAtIndexes:(CPIndexSet)theIndexes
366 {
367 if (_removeMany)
368 _removeMany(_proxyObject, _removeManySEL, theIndexes);
369 else if (_remove)
370 {
371 var index = [theIndexes lastIndex];
b98f0b1 @stevegeek Apply style rules to Foundation
stevegeek authored
372
5b00f7f @klaaspieter improve _CPKVCArray
klaaspieter authored
373 while (index !== CPNotFound)
374 {
375 _remove(_proxyObject, _removeSEL, index)
376 index = [theIndexes indexLessThanIndex:index];
377 }
378 }
379 else
380 {
381 var target = [[self _representedObject] copy];
382 [target removeObjectsAtIndexes:theIndexes];
383 [self _setRepresentedObject:target];
384 }
0b05b4b Add KVC+KVO support for "To Many" keys (i.e. Arrays).
Ross Boucher authored
385 }
386
387 - (void)replaceObjectAtIndex:(unsigned)anIndex withObject:(id)anObject
388 {
5b00f7f @klaaspieter improve _CPKVCArray
klaaspieter authored
389 [self replaceObjectsAtIndexes:[CPIndexSet indexSetWithIndex:anIndex] withObjects:[anObject]]
390 }
0b05b4b Add KVC+KVO support for "To Many" keys (i.e. Arrays).
Ross Boucher authored
391
5b00f7f @klaaspieter improve _CPKVCArray
klaaspieter authored
392 - (void)replaceObjectsAtIndexes:(CPIndexSet)theIndexes withObjects:(CPArray)theObjects
393 {
394 if (_replaceMany)
395 return _replaceMany(_proxyObject, _replaceManySEL, theIndexes, theObjects);
396 else if (_replace)
397 {
398 var i = 0,
399 index = [theIndexes firstIndex];
b98f0b1 @stevegeek Apply style rules to Foundation
stevegeek authored
400
5b00f7f @klaaspieter improve _CPKVCArray
klaaspieter authored
401 while (index !== CPNotFound)
402 {
403 _replace(_proxyObject, _replaceSEL, index, [theObjects objectAtIndex:i++]);
404 index = [theIndexes indexGreaterThanIndex:index];
405 }
406 }
407 else
408 {
409 var target = [[self _representedObject] copy];
410 [target replaceObjectsAtIndexes:theIndexes withObjects:theObjects];
411 [self _setRepresentedObject:target];
412 }
0b05b4b Add KVC+KVO support for "To Many" keys (i.e. Arrays).
Ross Boucher authored
413 }
414
415 @end
416
417
e2ead56 @aparajita Collection KVC fixes, nextObject correctness
aparajita authored
418 // KVC on CPArray objects act on each item of the array, rather than on the array itself
0b05b4b Add KVC+KVO support for "To Many" keys (i.e. Arrays).
Ross Boucher authored
419
e2ead56 @aparajita Collection KVC fixes, nextObject correctness
aparajita authored
420 @implementation CPArray (CPKeyValueCoding)
0b05b4b Add KVC+KVO support for "To Many" keys (i.e. Arrays).
Ross Boucher authored
421
422 - (id)valueForKey:(CPString)aKey
423 {
424 if (aKey.indexOf("@") === 0)
425 {
426 if (aKey.indexOf(".") !== -1)
b746824 @aljungberg Formatting.
aljungberg authored
427 [CPException raise:CPInvalidArgumentException reason:"called valueForKey: on an array with a complex key (" + aKey + "). use valueForKeyPath:"];
0b05b4b Add KVC+KVO support for "To Many" keys (i.e. Arrays).
Ross Boucher authored
428
e2ead56 @aparajita Collection KVC fixes, nextObject correctness
aparajita authored
429 if (aKey === "@count")
0b05b4b Add KVC+KVO support for "To Many" keys (i.e. Arrays).
Ross Boucher authored
430 return length;
b98f0b1 @stevegeek Apply style rules to Foundation
stevegeek authored
431
e2ead56 @aparajita Collection KVC fixes, nextObject correctness
aparajita authored
432 return [self valueForUndefinedKey:aKey];
0b05b4b Add KVC+KVO support for "To Many" keys (i.e. Arrays).
Ross Boucher authored
433 }
434 else
435 {
436 var newArray = [],
437 enumerator = [self objectEnumerator],
438 object;
b98f0b1 @stevegeek Apply style rules to Foundation
stevegeek authored
439
6291804 Support, fixes, and tests for KVC array operators.
Ross Boucher authored
440 while ((object = [enumerator nextObject]) !== nil)
0b05b4b Add KVC+KVO support for "To Many" keys (i.e. Arrays).
Ross Boucher authored
441 {
442 var value = [object valueForKey:aKey];
b98f0b1 @stevegeek Apply style rules to Foundation
stevegeek authored
443
6291804 Support, fixes, and tests for KVC array operators.
Ross Boucher authored
444 if (value === nil || value === undefined)
445 value = [CPNull null];
b98f0b1 @stevegeek Apply style rules to Foundation
stevegeek authored
446
0b05b4b Add KVC+KVO support for "To Many" keys (i.e. Arrays).
Ross Boucher authored
447 newArray.push(value);
448 }
b98f0b1 @stevegeek Apply style rules to Foundation
stevegeek authored
449
0b05b4b Add KVC+KVO support for "To Many" keys (i.e. Arrays).
Ross Boucher authored
450 return newArray;
451 }
452 }
453
454 - (id)valueForKeyPath:(CPString)aKeyPath
455 {
e2ead56 @aparajita Collection KVC fixes, nextObject correctness
aparajita authored
456 if (!aKeyPath)
457 [self valueForUndefinedKey:@"<empty path>"];
458
6ea4aa0 @aparajita Much more efficient test for first character of string
aparajita authored
459 if (aKeyPath.charAt(0) === "@")
b98f0b1 @stevegeek Apply style rules to Foundation
stevegeek authored
460 {
6291804 Support, fixes, and tests for KVC array operators.
Ross Boucher authored
461 var dotIndex = aKeyPath.indexOf("."),
da84964 Fix two problems with KVC:
Ross Boucher authored
462 operator,
463 parameter;
b98f0b1 @stevegeek Apply style rules to Foundation
stevegeek authored
464
da84964 Fix two problems with KVC:
Ross Boucher authored
465 if (dotIndex !== -1)
466 {
467 operator = aKeyPath.substring(1, dotIndex);
b98f0b1 @stevegeek Apply style rules to Foundation
stevegeek authored
468 parameter = aKeyPath.substring(dotIndex + 1);
da84964 Fix two problems with KVC:
Ross Boucher authored
469 }
470 else
471 operator = aKeyPath.substring(1);
472
e2ead56 @aparajita Collection KVC fixes, nextObject correctness
aparajita authored
473 return [_CPCollectionKVCOperator performOperation:operator withCollection:self propertyPath:parameter];
0b05b4b Add KVC+KVO support for "To Many" keys (i.e. Arrays).
Ross Boucher authored
474 }
475 else
476 {
477 var newArray = [],
478 enumerator = [self objectEnumerator],
479 object;
b98f0b1 @stevegeek Apply style rules to Foundation
stevegeek authored
480
6291804 Support, fixes, and tests for KVC array operators.
Ross Boucher authored
481 while ((object = [enumerator nextObject]) !== nil)
0b05b4b Add KVC+KVO support for "To Many" keys (i.e. Arrays).
Ross Boucher authored
482 {
483 var value = [object valueForKeyPath:aKeyPath];
b98f0b1 @stevegeek Apply style rules to Foundation
stevegeek authored
484
6291804 Support, fixes, and tests for KVC array operators.
Ross Boucher authored
485 if (value === nil || value === undefined)
486 value = [CPNull null];
b98f0b1 @stevegeek Apply style rules to Foundation
stevegeek authored
487
0b05b4b Add KVC+KVO support for "To Many" keys (i.e. Arrays).
Ross Boucher authored
488 newArray.push(value);
489 }
b98f0b1 @stevegeek Apply style rules to Foundation
stevegeek authored
490
0b05b4b Add KVC+KVO support for "To Many" keys (i.e. Arrays).
Ross Boucher authored
491 return newArray;
492 }
493 }
494
495 - (void)setValue:(id)aValue forKey:(CPString)aKey
496 {
497 var enumerator = [self objectEnumerator],
498 object;
b98f0b1 @stevegeek Apply style rules to Foundation
stevegeek authored
499
e2ead56 @aparajita Collection KVC fixes, nextObject correctness
aparajita authored
500 while ((object = [enumerator nextObject]) !== nil)
0b05b4b Add KVC+KVO support for "To Many" keys (i.e. Arrays).
Ross Boucher authored
501 [object setValue:aValue forKey:aKey];
502 }
503
504 - (void)setValue:(id)aValue forKeyPath:(CPString)aKeyPath
505 {
506 var enumerator = [self objectEnumerator],
507 object;
b98f0b1 @stevegeek Apply style rules to Foundation
stevegeek authored
508
e2ead56 @aparajita Collection KVC fixes, nextObject correctness
aparajita authored
509 while ((object = [enumerator nextObject]) !== nil)
0b05b4b Add KVC+KVO support for "To Many" keys (i.e. Arrays).
Ross Boucher authored
510 [object setValue:aValue forKeyPath:aKeyPath];
511 }
512
513 @end
514
515 @implementation CPArray (KeyValueObserving)
516
517 - (void)addObserver:(id)anObserver toObjectsAtIndexes:(CPIndexSet)indexes forKeyPath:(CPString)aKeyPath options:(unsigned)options context:(id)context
518 {
519 var index = [indexes firstIndex];
b98f0b1 @stevegeek Apply style rules to Foundation
stevegeek authored
520
0b05b4b Add KVC+KVO support for "To Many" keys (i.e. Arrays).
Ross Boucher authored
521 while (index >= 0)
522 {
523 [self[index] addObserver:anObserver forKeyPath:aKeyPath options:options context:context];
524
525 index = [indexes indexGreaterThanIndex:index];
526 }
527 }
528
529 - (void)removeObserver:(id)anObserver fromObjectsAtIndexes:(CPIndexSet)indexes forKeyPath:(CPString)aKeyPath
530 {
531 var index = [indexes firstIndex];
b98f0b1 @stevegeek Apply style rules to Foundation
stevegeek authored
532
0b05b4b Add KVC+KVO support for "To Many" keys (i.e. Arrays).
Ross Boucher authored
533 while (index >= 0)
534 {
535 [self[index] removeObserver:anObserver forKeyPath:aKeyPath];
536
537 index = [indexes indexGreaterThanIndex:index];
538 }
539 }
540
541 @end
Something went wrong with that request. Please try again.