背景
有时候我们需要维护一个,有顺序的数组,如数据源带有优先级的,低优先级排起数组前面,高优先级排素组后面。为了动态高效维护该“数组”,可以用CFBinaryHeapCreate。
CFBinaryHeapCreate
Creates a new mutable or fixed-mutable binary heap.
简要代码演示:
- (instancetype)init
{
if (self = [super init]) {
CFBinaryHeapCallBacks callbacks = (CFBinaryHeapCallBacks) {
.version = 0,
.retain = &KGModuleItemPriorityRetain,
.release = &KGModuleItemPriorityRelease,
.copyDescription = &CFCopyDescription,
.compare = &KGModuleItemPriorityCompare
};
_modules = CFBinaryHeapCreate(kCFAllocatorDefault, 0, &callbacks, NULL);
_moduleCache = [NSMutableDictionary dictionary];
}
return self;
}
static const void *KGModuleItemPriorityRetain(CFAllocatorRef allocator, const void *ptr) {
return CFRetain(ptr);
}
static void KGModuleItemPriorityRelease(CFAllocatorRef allocator, const void *ptr) {
CFRelease(ptr);
}
static CFComparisonResult KGModuleItemPriorityCompare(const void *ptr1, const void *ptr2, void *info)
{
KGAppModuleModel *item1 = (__bridge KGAppModuleModel *)ptr1;
KGAppModuleModel *item2 = (__bridge KGAppModuleModel *)ptr2;
if (item1.priority < item2.priority) { // greator first
return kCFCompareLessThan;
}
if (item1.priority > item2.priority) {
return kCFCompareGreaterThan;
}
if (item1.sequence > item2.sequence) { // lesser first
return kCFCompareLessThan;
}
if (item1.sequence < item2.sequence) {
return kCFCompareGreaterThan;
}
return kCFCompareEqualTo;
}
- (void)kgEnumerateModulesUsingBlock:(__attribute__((noescape)) void (^)(id module, BOOL *stop))block
{
CFIndex count = CFBinaryHeapGetCount(_modules);
const void **list = calloc(count, sizeof(const void *));
CFBinaryHeapGetValues(_modules, list);
CFArrayRef objects = CFArrayCreate(kCFAllocatorDefault, list, count, &kCFTypeArrayCallBacks);
NSArray *items = (__bridge_transfer NSArray *)objects;
[items enumerateObjectsWithOptions:NSEnumerationReverse
usingBlock:^(KGAppModuleModel * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
block(obj.module, stop);
}];
}
备注:
CFBinaryHeapAddValue,该函数作用,把对象加入CF管理,同时把OC管理的对象生命周期CF管理,会触发KGModuleItemPriorityRetain。
CFBinaryHeapGetValues,该函数作用是把之前加入对堆的数据取出来,存入到一个我们自定义的C数组里面去,取出来的结果是根据我们的排序规则KGModuleItemPriorityCompare排序的,是有序的。该函数会触发KGModuleItemPriorityRetain,本质是调用了CFBinaryHeapAddValue,也会触发KGModuleItemPriorityRelease。