为什么要实现一个tlist类,object-c自带nsarray和nsmutarray类,但这两个类都只能管理id类型也就是必须是nsobject或者是继承自nsobject的类型,因为在addobject和removeobject的时候,会去调用nsobject的retain和release方法对计数器加1和减1。有些时候它替我们管理,比较方便,但在某些时候就觉得它多管闲事了,感觉不通用。因此,我们更希望一个能存放任意指针类型的tlist类,下面附代码:
头文件:
#define MaxListSize (int)21474883647/6
typedef enum
{
lnAdded,
lnExtracted,
lnDeleted
}TListNotifyication;
typedef void** PPointerList;
@protocol TListSortCompare
+(int)_Sort:(void*)Item1:(void*)Item2;
@end;
@interface TList : NSObject
{
@private
PPointerList 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*));