27 - (id)mutableArrayValueForKey:(
id)aKey
29 return [[_CPKVCArray alloc] initWithKey:aKey forProxyObject:self];
32 - (id)mutableArrayValueForKeyPath:(
id)aKeyPath
34 var dotIndex = aKeyPath.indexOf(
".");
39 var firstPart = aKeyPath.substring(0, dotIndex),
40 lastPart = aKeyPath.substring(dotIndex + 1);
42 return [[
self valueForKeyPath:firstPart] mutableArrayValueForKeyPath:lastPart];
68 Function _replaceMany;
70 SEL _objectAtIndexSEL;
71 Function _objectAtIndex;
73 SEL _objectsAtIndexesSEL;
74 Function _objectsAtIndexes;
92 var ivars = class_copyIvarList(
self),
96 array[ivar_getName(ivars[count])] = nil;
101 - (id)initWithKey:(
id)aKey forProxyObject:(
id)anObject
106 _proxyObject = anObject;
108 var capitalizedKey = _key.charAt(0).toUpperCase() + _key.substring(1);
110 _insertSEL = sel_getName(
@"insertObject:in" + capitalizedKey +
"AtIndex:");
111 if ([_proxyObject respondsToSelector:_insertSEL])
112 _insert = [_proxyObject methodForSelector:_insertSEL];
114 _removeSEL = sel_getName(
@"removeObjectFrom" + capitalizedKey +
"AtIndex:");
115 if ([_proxyObject respondsToSelector:_removeSEL])
116 _remove = [_proxyObject methodForSelector:_removeSEL];
118 _replaceSEL = sel_getName(
@"replaceObjectIn" + capitalizedKey +
"AtIndex:withObject:");
119 if ([_proxyObject respondsToSelector:_replaceSEL])
120 _replace = [_proxyObject methodForSelector:_replaceSEL];
122 _insertManySEL = sel_getName(
@"insert" + capitalizedKey +
":atIndexes:");
123 if ([_proxyObject respondsToSelector:_insertManySEL])
124 _insertMany = [_proxyObject methodForSelector:_insertManySEL];
126 _removeManySEL = sel_getName(
@"remove" + capitalizedKey +
"AtIndexes:");
127 if ([_proxyObject respondsToSelector:_removeManySEL])
128 _removeMany = [_proxyObject methodForSelector:_removeManySEL];
130 _replaceManySEL = sel_getName(
@"replace" + capitalizedKey +
"AtIndexes:with" + capitalizedKey +
":");
131 if ([_proxyObject respondsToSelector:_replaceManySEL])
132 _replaceMany = [_proxyObject methodForSelector:_replaceManySEL];
134 _objectAtIndexSEL = sel_getName(
@"objectIn" + capitalizedKey +
"AtIndex:");
135 if ([_proxyObject respondsToSelector:_objectAtIndexSEL])
136 _objectAtIndex = [_proxyObject methodForSelector:_objectAtIndexSEL];
138 _objectsAtIndexesSEL = sel_getName(_key +
"AtIndexes:");
139 if ([_proxyObject respondsToSelector:_objectsAtIndexesSEL])
140 _objectsAtIndexes = [_proxyObject methodForSelector:_objectsAtIndexesSEL];
142 _countSEL = sel_getName(
@"countOf" + capitalizedKey);
143 if ([_proxyObject respondsToSelector:_countSEL])
144 _count = [_proxyObject methodForSelector:_countSEL];
146 _accessSEL = sel_getName(_key);
147 if ([_proxyObject respondsToSelector:_accessSEL])
148 _access = [_proxyObject methodForSelector:_accessSEL];
150 _setSEL = sel_getName(
@"set" + capitalizedKey +
":");
151 if ([_proxyObject respondsToSelector:_setSEL])
152 _set = [_proxyObject methodForSelector:_setSEL];
161 count = [
self count];
163 for (; i < count; i++)
164 [theCopy addObject:[self objectAtIndex:i]];
169 - (id)_representedObject
172 return _access(_proxyObject, _accessSEL);
174 return [_proxyObject valueForKey:_key];
177 - (void)_setRepresentedObject:(
id)anObject
180 return _set(_proxyObject, _setSEL, anObject);
182 [_proxyObject setValue:anObject forKey:_key];
188 return _count(_proxyObject, _countSEL);
190 return [[
self _representedObject] count];
193 - (int)indexOfObject:(
CPObject)anObject inRange:(CPRange)aRange
195 var index = aRange.location,
196 count = aRange.length,
197 shouldIsEqual = !!anObject.
isa;
199 for (; index < count; ++index)
201 var
object = [
self objectAtIndex:index];
203 if (anObject ===
object || shouldIsEqual && !!
object.
isa && [anObject
isEqual:
object])
210 - (int)indexOfObject:(
CPObject)anObject
212 return [
self indexOfObject:anObject inRange:CPMakeRange(0, [
self count])];
215 - (int)indexOfObjectIdenticalTo:(
CPObject)anObject inRange:(CPRange)aRange
217 var index = aRange.location,
218 count = aRange.length;
220 for (; index < count; ++index)
221 if (anObject === [self objectAtIndex:index])
227 - (int)indexOfObjectIdenticalTo:(
CPObject)anObject
229 return [
self indexOfObjectIdenticalTo:anObject inRange:CPMakeRange(0, [
self count])];
232 - (id)objectAtIndex:(
unsigned)anIndex
239 if (_objectsAtIndexes)
240 return _objectsAtIndexes(_proxyObject, _objectsAtIndexesSEL, theIndexes);
247 while ((index = [theIndexes indexGreaterThanIndex:index]) !==
CPNotFound)
248 objects.push(_objectAtIndex(_proxyObject, _objectAtIndexSEL, index));
253 return [[
self _representedObject] objectsAtIndexes:theIndexes];
256 - (void)addObject:(
id)anObject
258 [
self insertObject:anObject atIndex:[
self count]];
261 - (void)addObjectsFromArray:(
CPArray)anArray
264 count = [anArray
count];
269 - (void)insertObject:(
id)anObject atIndex:(
unsigned)anIndex
277 _insertMany(_proxyObject, _insertManySEL, theObjects, theIndexes);
280 var indexesArray = [];
283 for (var index = 0; index < [indexesArray count]; index++)
285 var objectIndex = [indexesArray objectAtIndex:index],
288 _insert(_proxyObject, _insertSEL,
object, objectIndex);
293 var target = [[
self _representedObject] copy];
295 [target insertObjects:theObjects atIndexes:theIndexes];
296 [
self _setRepresentedObject:target];
300 - (void)removeObject:(
id)anObject
302 [
self removeObject:anObject inRange:CPMakeRange(0, [
self count])];
305 - (void)removeObjectsInArray:(
CPArray)theObjects
310 index = [theObjects
count];
313 [indexes addIndex:[
self indexOfObject:[theObjects
objectAtIndex:index]]];
315 _removeMany(_proxyObject, _removeManySEL, indexes);
319 var index = [theObjects
count];
321 _remove(_proxyObject, _removeSEL, [
self indexOfObject:[theObjects objectAtIndex:index]]);
325 var target = [[
self _representedObject] copy];
326 [target removeObjectsInArray:theObjects];
327 [
self _setRepresentedObject:target];
331 - (void)removeObject:(
id)theObject inRange:(CPRange)theRange
334 _remove(_proxyObject, _removeSEL, [
self indexOfObject:theObject inRange:theRange]);
335 else if (_removeMany)
337 var index = [
self indexOfObject:theObject inRange:theRange];
338 _removeMany(_proxyObject, _removeManySEL, [
CPIndexSet indexSetWithIndex:index]);
344 while ((index = [
self indexOfObject:theObject inRange:theRange]) !==
CPNotFound)
346 [
self removeObjectAtIndex:index];
352 - (void)removeLastObject
357 - (void)removeObjectAtIndex:(
unsigned)anIndex
362 - (void)removeObjectsAtIndexes:(
CPIndexSet)theIndexes
365 _removeMany(_proxyObject, _removeManySEL, theIndexes);
372 _remove(_proxyObject, _removeSEL, index)
373 index = [theIndexes indexLessThanIndex:index];
378 var target = [[
self _representedObject] copy];
379 [target removeObjectsAtIndexes:theIndexes];
380 [
self _setRepresentedObject:target];
384 - (void)replaceObjectAtIndex:(
unsigned)anIndex withObject:(
id)anObject
389 - (void)replaceObjectsAtIndexes:(
CPIndexSet)theIndexes withObjects:(
CPArray)theObjects
392 return _replaceMany(_proxyObject, _replaceManySEL, theIndexes, theObjects);
400 _replace(_proxyObject, _replaceSEL, index, [theObjects objectAtIndex:i++]);
406 var target = [[
self _representedObject] copy];
407 [target replaceObjectsAtIndexes:theIndexes withObjects:theObjects];
408 [
self _setRepresentedObject:target];
421 if (aKey.indexOf(
"@") === 0)
423 if (aKey.indexOf(
".") !== -1)
426 if (aKey ===
"@count")
437 while ((
object = [enumerator nextObject]) !== nil)
439 var value = [object valueForKey:aKey];
441 if (value === nil || value === undefined)
444 newArray.push(value);
456 if (aKeyPath.charAt(0) ===
"@")
458 var dotIndex = aKeyPath.indexOf(
"."),
464 operator = aKeyPath.substring(1, dotIndex);
465 parameter = aKeyPath.substring(dotIndex + 1);
468 operator = aKeyPath.substring(1);
470 return [_CPCollectionKVCOperator performOperation:operator withCollection:self propertyPath:parameter];
478 while ((
object = [enumerator nextObject]) !== nil)
480 var value = [object valueForKeyPath:aKeyPath];
482 if (value === nil || value === undefined)
485 newArray.push(value);
497 while ((
object = [enumerator nextObject]) !== nil)
498 [object setValue:aValue forKey:aKey];
501 - (void)setValue:(
id)aValue forKeyPath:(
CPString)aKeyPath
506 while ((
object = [enumerator nextObject]) !== nil)
507 [object setValue:aValue forKeyPath:aKeyPath];
520 - (void)addObserver:(
id)anObserver forKeyPath:(
CPString)aKeyPath options:(CPKeyValueObservingOptions)anOptions context:(
id)aContext
522 [
CPException raise:CPInvalidArgumentException
reason:"[CPArray " + CPStringFromSelector(_cmd) + "] is not supported. Key path: " + aKeyPath];
531 - (void)removeObserver:(
id)anObserver forKeyPath:(
CPString)aKeyPath
533 [
CPException raise:CPInvalidArgumentException
reason:"[CPArray " + CPStringFromSelector(_cmd) + "] is not supported. Key path: " + aKeyPath];
539 - (void)addObserver:(
id)anObserver toObjectsAtIndexes:(
CPIndexSet)indexes forKeyPath:(
CPString)aKeyPath options:(
unsigned)options context:(
id)context
554 - (void)removeObserver:(
id)anObserver fromObjectsAtIndexes:(
CPIndexSet)indexes forKeyPath:(
CPString)aKeyPath