NSArray的原理及实现
NSArray的原理及实现
顾名思义,NSArray是一个数组类。使用NSArray类可以存储、处理元素。
Foundation框架中关于数组的类有2个:NSArray和NSMutableArray。NSArray是不可变数组,数组建立后不可以添加、删除元素,不可以更改元素。NSMutableArray是可变数组,数组建立后可以添加、删除、修改元素。而NSMutableArray是NSArray的子类,它继承了NSArray所有方法。
NSArray的实现十分简单。下面是它的成员
@interface NSArray : NSObject
{
id *_contents_array;
NSUInteger _count;
}
其中_contents_array是指向id数组的指针,_count为id数组的长度。如果数组由3个元素组成,则_contents_array=(id *)malloc(sizeof(id)*3),_count=3。
NSArray在初始化后便不能再修改了。NSArray有多个初始化方法。有一个初始化方法是最重要的---- (instancetype)initWithObjects:(const id [])objects count:(NSUInteger)cnt。其他初始化方法都是调用该方法完成NSArray的初始化。

-(id)initWithObjects:(id [])objects count:(NSUInteger)count
{
_contents_array=NULL;
_count=0;
if(count>0)
{
if(objects==NULL)
[NSException raise:NSInvalidArgumentException format:@"objects is NULL"];
_contents_array=(id *)malloc(sizeof(id)*count);
if(_contents_array==NULL)
[NSException raise:NSMallocException format:@"malloc out of memory"];
for (NSUInteger i=0; i<count; i++) {
if(objects[i]==nil)
[NSException raise:NSInvalidArgumentException format:@"object is nil"];
_contents_array[i]=objects[i];
[objects[i] retain];
}
_count=count;
}
return self;
}
方法首先判断cnt是否为0,如果为0, _contents_array和_count都为0,且直接返回。如果大于0,判断objects是否为NULL,如果是则抛出异常,如果不是继续执行。根据count申请个数为count的id数组,_contents_array指向该数组。如果内存申请失败,则抛出异常。申请成功后,将objects中的元素依次放入_contents_array中。并将元素的引用次数加一。如果元素中有值为nil,则抛出异常。最后设置_count为count。返回self。
-(id)initWithObjects:(id)firstObject,...
{
va_list ap;
va_start(ap, firstObject);
self=[self initWithObjects:firstObject arguments:ap];
va_end(ap);
return self;
}
方法使用可变参数来初始化数组。可变参数nil为结束。方法调用-(id)initWithObjects:(id)firstObject arguments:(va_list)ap方法完成初始化。
-(id)initWithObjects:(id)firstObject arguments:(va_list)ap
{
id *objects=NULL;
NSUInteger count=0;
//ap用于获取数组长度
//ap2用于获取数组元素
va_list ap2;
va_copy(ap2, ap);
count=1;
while(va_arg(ap, id)!=nil)
count++;
objects=(id *)malloc(sizeof(id)*count);
if(objects==NULL)
[NSException raise:NSMallocException format:@"malloc out of memory"];
objects[0]=firstObject;
for(NSUInteger i=1;i<count;i++)
{
objects[i]=va_arg(ap2, id);
}
self=[self initWithObjects:objects count:count];
free(objects);
va_end(ap2);
return self;
}
方法首先获取可变参数的个数,然后根据个数申请id数组,数组保存可变参数。最后调用- (instancetype)initWithObjects:(const id [])objects count:(NSUInteger)cnt完成初始化。
-(id)init
{
return [self initWithObjects:0 count:0];
}
初始化空数组。
-(id)initWithArray:(NSArray *)array
{
if(array==nil)
[NSException raise:NSInvalidArgumentException format:@"array is nil"];
id *objects=NULL;
NSUInteger count=0;
NSUInteger cnt=[array count];
if(cnt>0)
{
objects=(id *)malloc(sizeof(id)*cnt);
if(objects==NULL)
[NSException raise:NSMallocException format:@"malloc out of memory"];
[array getObjects:objects];
count=cnt;
}
self=[self initWithObjects:objects count:count];
if(objects)
free(objects);
return self;
}
方法首先判断参数是否有效,如果无效则抛出异常。 然后判断数组是否为空,如果为空则初始化为空数组。如果不为空,则根据数组个数申请id数组。如果申请失败,抛出异常。调用- (void)getObjects:(id[])objects将array数组的元素放入id数组。最后调用- (instancetype)initWithObjects:(const id [])objects count:(NSUInteger)cnt完成初始化。
方法- (NSUInteger)count和方法- (void)getObjects:(id[])objects在后面讲解。
-(id)initWithArray:(NSArray *)array copyItems:(BOOL)flag
{
if(array==nil)
[NSException raise:NSInvalidArgumentException format:@"array is nil"];
id *objects=NULL;
NSUInteger count=0;
NSUInteger cnt=[array count];
if(cnt>0)
{
objects=(id *)malloc(sizeof(id)*cnt);
if(objects==NULL)
[NSException raise:NSMallocException format:@"malloc out of memory"];
for(NSUInteger i=0;i<cnt;i++)
{
if(flag)
objects[i]=[[array objectAtIndex:i] copy];
else
objects[i]=[array objectAtIndex:i];
}
count=cnt;
}
self=[self initWithObjects:objects count:count];
if(cnt>0)
{
if(flag)
{
for(NSUInteger i=0;i<cnt;i++)
[objects[i] release];
}
free(objects);
}
return self;
}
方法类似于前一个方法,只是如果flag为YES,将array的元素复制到id数组时,复制的是元素执行copy方法后的值。
-(void)dealloc
{
if(_count>0)
{
for (NSUInteger i=0; i<_count; i++) {
[_contents_array[i] release];
}
free(_contents_array);
_contents_array=0;
}
[super dealloc];
}
释放数组对象。
初始化方法对应了一些构造方法。
+(id)array
{
return [[[self alloc] initWithObjects:0 count:0] autorelease];
}
构造空数组。
+(id)arrayWithArray:(NSArray *)array
{
return [[[self alloc] initWithArray:array] autorelease];
}
根据id数组构造对象。
+(id)arrayWithObject:(id)anObject
{
return [[[self alloc] initWithObjects:&anObject count:1] autorelease];
}
根据一个对象构造数组。如果anObject是nil,则抛出异常。
+(id)arrayWithObjects:(id)firstObject, ...
{
va_list ap;
va_start(ap, firstObject);
id *array=[[[self alloc] initWithObjects:firstObject arguments:ap] autorelease];
va_end(ap);
return array;
}
根据多个id对象构造对象。
+(id)arrayWithArray:(NSArray *)array
{
return [[[self alloc] initWithArray:array] autorelease];
}
根据数组构造数组。
数组初始化后,可以对数组进行操作。
获取数组元素个数是最简单的操作。
-(NSUInteger)count
{
return _count;
}
-(NSUInteger)hash
{
return [self count];
}
返回数组的hash值。
通过下标可以获取数组元素。
-(id)objectAtIndex:(NSUInteger)index
{
if(index>=_count)
[NSException raise:NSInvalidArgumentException format:@"out of index"];
return _contents_array[index];
}
如果下标超出长度,则抛出异常。
-(id)objectAtIndexedSubscript:(NSUInteger)index
{
return [self objectAtIndex:index];
}
等同于objectAtIndex方法。
-(NSArray *)objectsAtIndexes:(NSIndexSet *)indexes
{
id *objects=NULL;
NSUInteger count=0;
NSUInteger cnt=[indexes count];
if(cnt>0)
{
objects=(id *)malloc(sizeof(id)*cnt);
if(objects==NULL)
[NSException raise:NSMallocException format:@"malloc out of memery"];
NSUInteger i=0;
NSUInteger index=[indexes firstIndex];
while (index!=NSNotFound) {
objects[i]=[self objectAtIndex:index];
index=[indexes indexGreaterThanIndex:index];
i++;
}
count=cnt;
}
NSArray *array=[[[NSArray alloc] initWithObjects:objects count:count] autorelease];
if(objects)
free(objects);
return array;
}
返回下标列表对应的对象数组。如果indexs是nil,则抛出异常。调用- (id)objectAtIndex:(NSUInteger)index获取下标对应对象。
-(void)getObjects:(id [])aBuffer
{
if(aBuffer==NULL)
[NSException raise:NSInvalidArgumentException format:@"aBuffer is NULL"];
for(NSUInteger i=0;i<_count;i++)
aBuffer[i]=_contents_array[i];
}
获取数组中所有id对象。如果objects为NULL,则抛出异常。
-(void)getObjects:(id [])aBuffer range:(NSRange)aRange
{
if(aBuffer==NULL)
[NSException raise:NSInvalidArgumentException format:@"aBuffer is NULL"];
if(aRange.location>_count||aRange.length>_count-aRange.location)
[NSException raise:NSRangeException format:@"out of range"];
for(NSUInteger i=0;i<aRange.length;i++)
{
aBuffer[i]=_contents_array[i+aRange.location];
}
}
获取数组区间内的都有id对象。如果objects为NULL,则抛出异常。如果range超出数组范围,则抛出异常。
-(NSUInteger)indexOfObjectIdenticalTo:(id)anObject
{
if(anObject==nil)
[NSException raise:NSInvalidArgumentException format:@"anObject is nil"];
for(NSUInteger i=0;i<_count;i++)
{
if(_contents_array[i]==anObject)
return i;
}
return NSNotFound;
}
在数组中搜索对象值为anObject的元素的下标。如果成功返回下标,如果失败返回NSNotFound。如果anObject为nil,则抛出异常。
-(NSUInteger)indexOfObjectIdenticalTo:(id)anObject inRange:(NSRange)range
{
if(anObject==nil)
[NSException raise:NSInvalidArgumentException format:@"anObject is nil"];
if(range.location>[self count]||range.length>[self count]-range.location)
[NSException raise:NSRangeException format:@"out of range"];
for(NSUInteger i=range.location;i<range.location+range.length;i++)
{
if(anObject==_contents_array[i])
return i;
}
return NSNotFound;
}
在数组区间内搜索对象值为anObject的元素的下标。如果成功返回下标,如果失败返回NSNotFound。如果anObject为nil,则抛出异常。如果range超出数组的范围,则抛出异常。
-(NSUInteger)indexOfObject:(id)anObject
{
if(anObject==nil)
[NSException raise:NSInvalidArgumentException format:@"anObject is nil"];
for(NSUInteger i=0;i<_count;i++)
{
if([_contents_array[i] isEqual:anObject])
return i;
}
return NSNotFound;
}
在数组内搜索anObject对象。如果成功返回下标,如果失败返回NSNotFound。搜索的比较方式是- (BOOL)isEqual:(id)object方法。如果anObject为nil,则抛出异常
-(NSUInteger)indexOfObject:(id)anObject inRange:(NSRange)range
{
if(anObject==nil)
[NSException raise:NSInvalidArgumentException format:@"anObject is nil"];
if(range.location>[self count]||range.length>[self count]-range.location)
[NSException raise:NSRangeException format:@"out of range"];
for(NSUInteger i=range.location;i<range.location+range.length;i++)
{
if([anObject isEqual:_contents_array[i]])
return i;
}
return NSNotFound;
}
在数组区间内搜索anObject对象。如果成功返回下标,如果失败返回NSNotFound。搜索的比较方式是- (BOOL)isEqual:(id)object方法。如果anObject为nil,则抛出异常。如果range超出数组范围则抛出异常。
-(BOOL)containsObject:(id)anObject
{
NSUInteger i=[self indexOfObject:anObject];
if(i==NSNotFound)
return NO;
return YES;
}
判断anObject是否存在数组中。实际调用了- (NSUInteger)indexOfObject:(id)anObject方法判断。
-(id)firstObject
{
if([self count]==0)
return nil;
return _contents_array[0];
}
返回第一个元素,如果数组为空则返回nil。
-(id)lastObject
{
if(_count>0)
return _contents_array[_count-1];
return nil;
}
返回最后一个元素,如果数组为空则返回nil。
-(CCArray *)arrayByAddingObject:(id)anObject
{
if(anObject==nil)
[NSException raise:NSInvalidArgumentException format:@"anObject is nil"];
id *objects=NULL;
NSUInteger count=0;
count=[self count]+1;
objects=(id *)malloc(sizeof(id)*count);
if(objects==NULL)
[NSException raise:NSMallocException format:@"malloc out of memory"];
[self getObjects:objects];
objects[count-1]=anObject;
CCArray *array=[[[CCArray alloc] initWithObjects:objects count:count] autorelease];
free(objects);
return array;
}
将原数组与anObject构成一个新数组。如果anObject为空,则抛出异常。如果生成新的id数组失败则抛出异常。
-(NSArray *)arrayByAddingObjectsFromArray:(NSArray *)array
{
if(array==nil)
[NSException raise:NSInvalidArgumentException format:@"array is nil"];
id *objects=NULL;
NSUInteger count=0;
NSUInteger cnt1=[self count];
NSUInteger cnt2=[array count];
NSUInteger cnt=cnt1+cnt2;
if(cnt>0)
{
objects=(id *)malloc(sizeof(id)*cnt);
if(objects==NULL)
[NSException raise:NSMallocException format:@"malloc out of memory"];
[self getObjects:objects];
[self getObjects:objects+cnt1];
count=cnt;
}
NSArray *arr=[[[NSArray alloc] initWithObjects:objects count:count] autorelease];
if(objects)
free(objects);
return arr;
}
将原数组与数组otherArray合并生成新的数组。如果otherArray为空,则抛出异常。如果生成新的id数组失败则抛出异常。
-(NSArray *)subarrayWithRange:(NSRange)range
{
if(range.location>[self count]||range.length>[self count]-range.location)
[NSException raise:NSRangeException format:@"out of range"];
id *objects=NULL;
NSUInteger count=0;
NSUInteger cnt=range.length;
if(cnt>0)
{
objects=(id *)malloc(sizeof(id)*cnt);
if(objects==NULL)
[NSException raise:NSMallocException format:@"out of memory"];
[self getObjects:objects range:range];
count=cnt;
}
NSArray *array=[[[NSArray alloc] initWithObjects:objects count:count] autorelease];
if(objects)
free(objects);
return array;
}
取数组的子数组。如果range超出数组范围则抛出异常。
-(NSString *)componentsJoinedByString:(NSString *)separator
{
NSUInteger count=[self count];
NSMutableString *string=[NSMutableString stringWithCapacity:0];
if(count>0)
{
[string appendString:[[self objectAtIndex:0] description]];
for (NSUInteger i=1; i<count; i++) {
[string appendString:separator];
[string appendString:[[self objectAtIndex:i] description]];
}
}
return [[string copy] autorelease];
}
将数组对象生成的字符串以separator分隔符连接。数组对象调用description方法生成字符串。如果separator为nil,则抛出异常。将路径分量组成路径是该方法使用的一个例子。
-(id)firstObjectCommonWithArray:(CCArray *)otherArray
{
if(otherArray==nil)
[NSException raise:NSInvalidArgumentException format:@"otherArray is nil"];
NSUInteger count=[self count];
for (NSUInteger i=0; i<count; i++) {
if([otherArray containsObject:[self objectAtIndex:i]])
return [self objectAtIndex:i];
}
return nil;
}
返回数组与otherArray数组共同的第一个对象。
-(BOOL)isEqualToArray:(CCArray *)otherArray
{
if(otherArray==nil)
[NSException raise:NSInvalidArgumentException format:@"otherArray is nil"];
if(self==otherArray)
return YES;
NSUInteger count=[self count];
if(count!=[otherArray count])
return YES;
for (NSUInteger i=0; i<count; i++) {
if([[otherArray objectAtIndex:i] isEqual:[self objectAtIndex:i]]==NO)
return NO;
}
return YES;
}
判断两个数组是否相等。如果数组为nil,则抛出异常。
-(BOOL)isEqual:(id)object
{
if(self==object)
return YES;
if([self isKindOfClass:[NSArray class]]==NO)
return NO;
return [self isEqualToArray:object];
}
比较对象是否相等。
-(void)makeObjectsPerformSelector:(SEL)selector
{
for (NSUInteger i=0; i<_count; i++) {
[_contents_array[i] performSelector:selector];
}
}
数组的每个元素都执行aSelector
-(void)makeObjectsPerformSelector:(SEL)selector withObject:(id)argument
{
for (NSUInteger i=0; i<_count; i++) {
[_contents_array[i] performSelector:selector withObject:argument];
}
}
数组中每个元素都执行aSelector,aSelector带参数argument。
-(id)copy
{
return [self retain];
}
复制对象。对象为不可变数组。
-(id)mutableCopy
{
NSMutableArray *array=[[NSMutableArray alloc] initWithObjects:_contents_array count:_count];
return array;
}
复制对象。对象为可变数组。
-(BOOL)makeImmutable
{
return YES;
}
对象是否是不可变的。
使用枚举器可以方便的访问数组元素。NSArray实现了两个枚举器
@interface NSArrayEnumerator : NSEnumerator
{
NSArray *array;
NSUInteger pos;
}
-(id)initWithArray:(NSArray *)anArray;
@end
@implementation NSArrayEnumerator
-(id)initWithArray:(NSArray *)anArray
{
array=anArray;
[anArray retain];
pos=0;
return self;
}
-(id)nextObject
{
if(pos>=[array count])
return nil;
id obj=[array objectAtIndex:pos];
pos++;
return obj;
}
-(void)dealloc
{
[array release];
[super dealloc];
}
@end
-(NSEnumerator *)objectEnumerator
{
NSArrayEnumerator *enumerator=[[[NSArrayEnumerator alloc] initWithArray:self] autorelease];
return enumerator;
}
返回数组枚举器。
@interface NSArrayEnumeratorReverse: NSArrayEnumerator
@end
@implementation NSArrayEnumeratorReverse
-(id)initWithArray:(NSArray *)anArray
{
array=anArray;
[anArray retain];
pos=[anArray count];
return self;
}
-(id)nextObject
{
if(pos<=0)
return nil;
id obj=[array objectAtIndex:pos-1];
pos--;
return obj;
}
@end
-(NSEnumerator *)reverseObjectEnumerator
{
NSArrayEnumeratorReverse *enumerator=[[[NSArrayEnumeratorReverse alloc] initWithArray:self] autorelease];
return enumerator;
}
返回数组反向枚举器。
NSMutableArray是可变数组,是NSArray的子类,继承了NSArray的所有方法和属性。它的成员是:
@interface NSMutableArray : NSArray
{
//id *_contents_array;
//NSUInteger _count;
NSUInteger _capacity;
NSUInteger _grow_factor;
}
_contents_array和_count是NSArray的成员,NSMutableArray继承了这些成员。_contents_array指向id数组,_capacity是id数组的容量,也就是id数组的大小。_count是已赋值的id对象的大小。当_count的大小大于等于_capacity的大小,则将形成新的_capacity,_capacity=_capacity+_grow_factor。_grow_factor是数组扩展的大小。_contents_array也将重新申请内存,数组的大小是_capacity。_grow_factor也将修改。

-(id)initWithCapacity:(NSUInteger)cap
{
if(cap==0)
cap=1;
_contents_array=(id *)malloc(sizeof(id)*cap);
if(_contents_array==NULL)
[NSException raise:NSMallocException format:@"malloc out of memory"];
_capacity=cap;
_count=0;
_grow_factor=cap>1?cap/2:1;
return self;
}
根据容量初始化。如果numItems为0,则设置numItems为1。然后申请大小为numItems的id数组。_capacity设置为numItems。_grow_factor根据
_capacity设置。_grow_factor=_capacity<2?1:_capacity。这保证了数组一定会增长,数组增长的方式是_capacity=_capacity+_grow_factor。
-(id)initWithObjects:(id [])objects count:(NSUInteger)count
{
[self initWithCapacity:count];
if(count>0)
{
if(objects==0)
[NSException raise:NSInvalidArgumentException format:@"objects is nil"];
for(NSUInteger i=0;i<count;i++)
{
if(objects[i]==nil)
[NSException raise:NSInvalidArgumentException format:@"object[i] is nil"];
_contents_array[i]=objects[i];
[_contents_array[i] retain];
}
_count=count;
}
return self;
}
NSMutableArray修改了该方法。由于其他初始化方法都是调用该方法完成初始化的,所以此处修改后,其他初始化都已修改完成。构造方法也是同理。
-(id)init
{
return [self initWithCapacity:0];
}
初始化空数组。
-(NSMutableArray *)arrayWithCapacity:(NSUInteger)cap
{
return [[[NSMutableArray alloc] initWithCapacity:cap] autorelease];
}
根据容量构造数组。
-(void)addObject:(id)anObject
{
if(anObject==nil)
[NSException raise:NSInvalidArgumentException format:@"anObject is nil"];
if(_count>=_capacity)
{
_contents_array=(id *)realloc(_contents_array, (_capacity+_grow_factor)*sizeof(id));
if(_contents_array==NULL)
[NSException raise:NSMallocException format:@"malloc out of memory"];
_capacity=_capacity+_grow_factor;
_grow_factor=_capacity/2;
}
_contents_array[_count]=[anObject retain];
_count++;
}
添加数组元素。如果anObject为nil,则抛出异常。如果数组大小超出数组容量,则扩展数组大小。
-(void)addObjectsFromArray:(CCArray *)array
{
if(array==nil)
[NSException raise:NSInvalidArgumentException format:@"array is nil"];
for (NSUInteger i=0; i<[array count]; i++) {
[self addObject:[array objectAtIndex:i]];
}
}
添加数组。如果otherArray为nil,则抛出异常。
方法依次调用addObject添加对象。
-(void)insertObject:(id)anObject atIndex:(NSUInteger)index
{
if(anObject==nil)
[NSException raise:NSInvalidArgumentException format:@"anObject is nil"];
if(index>[self count])
[NSException raise:NSInvalidArgumentException format:@"index out of count"];
if(_count>=_capacity)
{
NSUInteger size=_capacity+_grow_factor;
_contents_array=realloc(_contents_array, sizeof(id)*size);
if(_contents_array==NULL)
[NSException raise:NSMallocException format:@"malloc out of memory"];
_capacity=size;
_grow_factor=_capacity>1?_capacity/2:1;
}
memmove(&_contents_array[index+1], &_contents_array[index], (_count-index)*sizeof(id));
_contents_array[index]=[anObject retain];
_count++;
}
插入数组元素。如果anObject为nil,则抛出异常。如果index大于数组大小,则抛出异常。插入位置放anObject,anObject执行retain方法。插入位置后的对象向后移动。
- (void)insertObjects:(NSArray *)objects atIndexes:(NSIndexSet *)indexes
{
if(objects==nil||indexes==nil)
[NSException raise:NSInvalidArgumentException format:@"objects = nil || indexs = nil"];
if([objects count]!=[indexes count])
[NSException raise:NSInvalidArgumentException format:@"count not same"];
NSUInteger i=[indexes firstIndex];
NSUInteger j=0;
while (i!=NSNotFound) {
[self insertObject:[objects objectAtIndex:j] atIndex:i];
i=[indexes indexGreaterThanIndex:i];
j++;
}
}
在下标序列处插入元素
-(void)removeLastObject
{
if(_count==0)
[NSException raise:NSInvalidArgumentException format:@"count = 0"];
[_contents_array[_count-1] release];
_count--;
}
删除最后一个元素。如果数组为空,则抛出异常。
-(void)removeObjectAtIndex:(NSUInteger)index
{
if(index>=[self count])
[NSException raise:NSInvalidArgumentException format:@"index >= count"];
[_contents_array[index] release];
for(NSUInteger i=index+1;i<_count;i++)
{
_contents_array[i-1]=_contents_array[i];
}
_count--;
}
删除下标对应的元素。如果index大于或等于数组长度,则抛出异常。删除元素执行release方法。删除位置后的元素向前移动。
-(void)removeAllObject
{
for(NSUInteger i=0;i<_count;i++)
{
[_contents_array[i] release];
}
_count=0;
}
删除所有元素。删除的元素执行release方法。
-(void)removeObjectIdenticalTo:(id)anObject
{
if(anObject==nil)
[NSException raise:NSInvalidArgumentException format:@"anObject is nil"];
for (NSInteger i=_count-1; i>=0; i--) {
if(_contents_array[i]==anObject)
{
[self removeObjectAtIndex:i];
}
}
}
删除与anObject值相等的元素。
-(void)removeObjectIdenticalTo:(id)anObject inRange:(NSRange)range
{
if(anObject==nil)
[NSException raise:NSInvalidArgumentException format:@"anObject is nil"];
if(range.location>[self count]||range.length>[self count]-range.location)
[NSException raise:NSRangeException format:@"out of range"];
for(NSUInteger i=range.location;i<range.location+range.length;i++)
{
if(anObject==_contents_array[i])
{
[self removeObjectAtIndex:i];
}
}
}
删除区间内与anObject值相等的元素。
-(void)removeObject:(id)anObject
{
if(anObject==nil)
[NSException raise:NSInvalidArgumentException format:@"anObject is nil"];
for(NSInteger i=_count-1;i>=0;i--)
{
if([anObject isEqual:_contents_array[i]])
{
[self removeObjectAtIndex:i];
}
}
}
删除与anObject相等的元素。相等是通过- (BOOL)isEqual:(id)object方法判断的。
-(void)removeObjectsInRange:(NSRange)range
{
if(range.location>[self count]||range.length>[self count]-range.location)
[NSException raise:NSRangeException format:@"out of range"];
for (NSUInteger i=range.location; i<range.location+range.length; i++) {
[_contents_array[i] release];
}
NSUInteger loc=range.location;
NSUInteger len=range.length;
NSUInteger end=loc+len;
memmove(&_contents_array[loc], &_contents_array[end], (_count-end)*sizeof(id));
_count-=range.length;
}
在区间内删除与anObject相等的元素。相等是通过- (BOOL)isEqual:(id)object方法判断的。
- (void)removeObjectsFromIndices:(NSUInteger *)indices numIndices:(NSUInteger)cnt
{
NSMutableIndexSet *set=[[[NSMutableIndexSet alloc] init] autorelease];
for(NSUInteger i=0;i<cnt;i++)
{
[set addIndex:indices[i]];
}
[self removeObjectsAtIndexes:set];
}
删除所有下标对应的元素。
- (void)removeObjectsAtIndexes:(NSIndexSet *)indexes
{
if(indexes==nil)
[NSException raise:NSInvalidArgumentException format:@"indexes == nil"];
NSUInteger index=[indexes lastIndex];
while (index!=NSNotFound) {
[self removeObjectAtIndex:index];
index=[indexes indexLessThanIndex:index];
}
}
删除下标序列对应的元素。
-(void)removeObjectsInArray:(NSArray *)array
{
if(array==nil)
[NSException raise:NSInvalidArgumentException format:@"array == nil"];
for (NSUInteger i=0; i<[array count]; i++) {
[self removeObject:[array objectAtIndex:i]];
}
}
删除与otherArray中元素相等的元素。相等是通过- (BOOL)isEqual:(id)object方法判断的
-(void)removeObjectsInRange:(NSRange)range
{
if(range.location>[self count]||range.length>[self count]-range.location)
[NSException raise:NSRangeException format:@"out of range"];
for (NSUInteger i=range.location; i<range.location+range.length; i++) {
[_contents_array[i] release];
}
for (NSUInteger i=range.location,j=range.location+range.length; i<[self count]-(range.location+range.length); i++,j++) {
_contents_array[i]=_contents_array[j];
}
_count-=range.length;
}
删除数组区间的元素。如果range超出数组范围,则抛出异常。
-(void)replaceObjectAtIndex:(NSUInteger)index withObject:(id)anObject
{
if(anObject==nil)
[NSException raise:NSInvalidArgumentException format:@"anObject == nil"];
if(index>=_count)
[NSException raise:NSInvalidArgumentException format:@"index out of count"];
id obj =_contents_array[index];
_contents_array[index]=[anObject retain];
[obj release];
}
修改下标对应的元素。如果下标大于等于数组长度,则抛出异常。
-(void)replacesObjectInRange:(NSRange)aRange withObjectsFromArray:(NSArray *)array
{
if(aRange.location>[self count]||aRange.length>[self count]-aRange.location)
[NSException raise:NSRangeException format:@"aRange out of count"];
if(array==nil)
[NSException raise:NSInvalidArgumentException format:@"array == nil"];
[self removeObjectsInRange:aRange];
for(NSInteger i=[array count]-1;i>=0;i--)
{
[self insertObject:[array objectAtIndex:i] atIndex:aRange.location];
}
}
使用otherArray替换区间内的元素。
-(void)replacesObjectInRange:(NSRange)aRange withObjectsFromArray:(NSArray *)array range:(NSRange)anotherRange
{
[self replacesObjectInRange:aRange withObjectsFromArray:[array subarrayWithRange:anotherRange]];
}
使用otherArray区间内的元素替换原数组区间内的元素。
- (void)replaceObjectsAtIndexes:(NSIndexSet *)indexes withObjects:(NSArray *)objects
{
if(indexes==nil)
[NSException raise:NSInvalidArgumentException format:@"indexes == nil"];
if(objects==nil)
[NSException raise:NSInvalidArgumentException format:@"objects == nil"];
if([indexes count]!=[objects count])
[NSException raise:NSInvalidArgumentException format:@"count not same"];
NSUInteger index=[indexes firstIndex];
NSUInteger j=0;
while (index!=NSNotFound) {
[self replaceObjectAtIndex:index withObject:[objects objectAtIndex:j]];
index=[indexes indexGreaterThanIndex:index];
j++;
}
}
替换下标对应的元素。
-(void)exchangeObjectAtIndex:(NSUInteger)idx1 withObjectAtIndex:(NSUInteger)idx2
{
if(idx1>=[self count])
[NSException raise:NSInvalidArgumentException format:@"idx1 out of count"];
if(idx2>=[self count])
[NSException raise:NSInvalidArgumentException format:@"idx2 out of count"];
if(idx1!=idx2)
{
id obj=_contents_array[idx1];
_contents_array[idx1]=_contents_array[idx2];
_contents_array[idx2]=obj;
}
}
交换两个元素。
-(void)setArray:(NSArray *)array
{
[self removeAllObject];
[self addObjectsFromArray:array];
}
设置数组。
-(void)setObject:(id)anObject atIndexedSubscript:(NSUInteger)idx
{
if(anObject==nil)
[NSException raise:NSInvalidArgumentException format:@"anObject == nil"];
if(idx>[self count])
[NSException raise:NSInvalidArgumentException format:@"idx out of count"];
if(idx==[self count])
[self addObject:anObject];
else
[self replaceObjectAtIndex:idx withObject:anObject];
}
设置元素。如果idx小于数组长度,则执行replaceObjectAtIndex。如果等于数组长度则执行addObject。如果大于数组长度则抛出异常。
-(id)copy
{
NSArray *array=[[NSArray alloc] initWithObjects:_contents_array count:_count];
return array;
}
复制对象。对象为不可变数组。
-(BOOL)makeImmutable
{
return NO;
}
对象是否是不可变的。
浙公网安备 33010602011771号