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;
}

对象是否是不可变的。

posted on 2020-04-26 10:29  鬼手渔翁  阅读(1)  评论(0)    收藏  举报

导航