为什么要实现一个tlist类,object-c自带nsarray和nsmutarray类,但这两个类都只能管理id类型也就是必须是nsobject或者是继承自nsobject的类型,因为在addobject和removeobject的时候,会去调用nsobject的retain和release方法对计数器加1和减1。有些时候它替我们管理,比较方便,但在某些时候就觉得它多管闲事了,感觉不通用。因此,我们更希望一个能存放任意指针类型的tlist类,下面附代码:
头文件:#define MaxListSize (int)21474883647/6typedef enum
{lnAdded,lnExtracted,lnDeleted
}TListNotifyication;typedef void** PPointerList;@protocol TListSortCompare
+(int)_Sort:(void*)Item1:(void*)Item2;
@end;@interface TList : NSObject
{@privatePPointerList FList;int FCount;int FCapacity;
}
//protected function
-(void)_Notify:(void*)P:(TListNotifyication)Action;
//protected function virtual
-(void)_Grow;
//public function
-(void)dealloc;
-(int)Add:(void*)Item;
-(void)Delete:(int)Index;
-(TList*)Expaned;
-(void*)Extract:(void*)Item;
-(void*)First;
-(int)IndexOf:(void*)Item;
-(void)Insert:(int)Index:(void*)Item;
-(void*)Last;
-(void)Move:(int)CurIndex:(int)NewIndex;
-(int)Remove:(void*)Item;
-(void)Pack;
-(void)Sort:(id<TListSortCompare>)Compare;
-(void)SetCapacity:(int)NewCapacity;
-(int)Capacity;
-(void)SetCount:(int)NewCount;
-(int)Count;
-(void*)Get:(int)Index;
-(void)Put:(int)Index:(void*)Item;
-(PPointerList)List;
-(void)Exchange:(int)Index1:(int)Index2;
//public function virtual
-(void)Clear;
@end源文件:
//快速排序
void QuickSort(PPointerList List, int L, int R,id<TListSortCompare> SCompare)
{int i, j;void* p, *t;do {i = L;j = R;p = List[(L + R) >> 1];do{while([SCompare _Sort:List[i], p] < 0)++i;while([SCompare _Sort:List[j], p] > 0)--j;if(i <= j){t = List[i];List[i] = List[j];List[j] = t;++i;--j;}}while(i < j);if(L < j)QuickSort(List, L, j, SCompare);L = i;}while(i <= R);}@implementation TList
-(void)dealloc
{[self Clear];[super dealloc];
};-(void)Delete:(int)Index
{if((Index < 0)||(Index >= FCount)){raise(0);return;}void* temp = [self Get:Index];--FCount;if(Index < FCount)memcpy(&FList[Index], &FList[Index + 1], (FCount - Index) * sizeof(void*));if(temp)[self _Notify:temp :lnDeleted];
}-(void)Exchange:(int)Index1 :(int)Index2
{if((Index1 < 0)||(Index1 >= FCount)){raise(0);return;}if((Index2 < 0)||(Index2 >= FCount)){raise(0);return;}void* item = FList[Index1];FList[Index1] = FList[Index2];FList[Index2] = item;
}-(void*)Extract:(void *)Item
{void* res = nil;int i = [self IndexOf:Item];if(i >= 0){res = Item;FList[i] = nil;[self Delete:i];[self _Notify:res :lnExtracted];}return res;
}-(void)_Notify:(void *)P :(TListNotifyication)Action
{//nothing
}-(int)Add:(void*)Item
{int res = FCount;if(res == FCapacity)[self _Grow]; memcpy(&FList[res], &Item, sizeof(void*));++FCount; if(Item)[self _Notify:Item:lnAdded];return res;
};-(int)Capacity
{return FCapacity;
}-(int)Count
{return FCount;
}-(PPointerList)List
{return FList;
}-(void)Clear
{[self SetCount:0];[self SetCapacity:0];
}
-(TList*)Expaned
{if(FCount == FCapacity)[self _Grow];return self;
}-(void*)First
{return [self Get:0];
}-(void*)Last
{return [self Get:FCount - 1];
}-(void)Move:(int)CurIndex :(int)NewIndex
{if(CurIndex != NewIndex){if((NewIndex < 0)||(NewIndex >= FCount))return;void* item = [self Get:CurIndex];FList[CurIndex] = nil;[self Delete:CurIndex];[self Insert:NewIndex :nil];FList[NewIndex] = item;}
}-(void)Put:(int)Index :(void *)Item
{if((Index < 0)||(Index >= FCount)){raise(0);return;}if(Item != FList[Index]){void* temp = FList[Index];FList[Index] = Item;if(temp)[self _Notify:temp : lnDeleted];if(Item)[self _Notify:Item:lnAdded];}
}-(int)Remove:(void *)Item
{int res = [self IndexOf:Item];if(res >= 0)[self Delete:res];return res;
}-(void)Pack
{for(int i = FCount - 1; i >= 0; --i){if([self Get:i] == nil)[self Delete:i];}
}-(void)SetCapacity:(int)NewCapacity
{if((NewCapacity < FCount)||(NewCapacity > MaxListSize)){raise(0);return;}if(NewCapacity != FCapacity){FList = realloc(FList, NewCapacity * sizeof(void*));