Создавая и Используя древовидные структуры
С непрозрачным типом CFTree можно создать древовидные структуры в памяти для представления иерархических организаций информации. В таких структурах каждый древовидный узел имеет точно одно семенное дерево (за исключением корневого дерева, не имеющего никакого родителя), и может иметь многократные дочерние деревья. Каждому объекту CFTree в расширенной структуре связали контекст с ним; этот контекст включает некоторые определенные с помощью программы данные, а также обратные вызовы, воздействующие на те данные. Определенные с помощью программы данные часто используются, чтобы хранить информацию о каждом узле в структуре.
Эта задача обсуждает, как создать объекты CFTree, вместить их в структуру деревьев, и затем позже найти, получает и изменяет их. Первый параметр большинства функций CFTree является ссылкой на родительский объект CFTree; сама работа обычно вовлекает один или несколько дочерних элементов того родителя. Другими словами, большинство подпрограмм CFTree работает «вниз» иерархия от данного родителя, но влияния только дочерние элементы того родителя.
Один важный факт для запоминания с работой с объектами CFTree - то, который функционирует, которые воздействуют на дочерние элементы, не являются рекурсивными. Они влияют только на непосредственные дочерние деревья. Если Вы хотите пересечь все поддеревья от какого-либо данного родительского узла, Ваш код должен предоставить пересекающуюся логику.
Создание объекта CFTree
Прежде чем можно будет создать объект CFTree, необходимо определить его контекст. Это означает, что необходимо объявить и инициализировать структуру CFTreeContext
. Эта структура имеет следующее определение:
typedef struct { |
CFIndex version; |
void *info; |
const void *(*retain)(const void *info); |
void (*release)(const void *info); |
CFStringRef (*copyDescription)(const void *info); |
} CFTreeContext; |
info
элемент этой структуры указывает на данные, что Вы определяете (и выделите, если необходимый). Другие элементы структуры контекста (за исключением элемента версии) указывают на функции, берущие info
указатель как параметр и выполняет определенные операции, связанные с указанным данные, такие как сохранение его, выпуск его и описание его.
Когда Вы должным образом инициализировали a CFTreeContext
структура, вызовите CFTreeCreate
функция, передающая в указателе на структуру. Перечисление 1 дает пример этого метода.
Перечисление 1 , Создающее объект CFTree
static CFTreeRef CreateMyTree(CFAllocatorRef allocator) { |
MyTreeInfo *info; |
CFTreeContext ctx; |
info = CFAllocatorAllocate(allocator, sizeof(MyTreeInfo), 0); |
info->address = 0; |
info->symbol = NULL; |
info->countCurrent = 0; |
info->countTotal = 0; |
ctx.version = 0; |
ctx.info = info; |
ctx.retain = AllocTreeInfo; |
ctx.release = FreeTreeInfo; |
ctx.copyDescription = NULL; |
return CFTreeCreate(allocator, &ctx); |
} |
Поскольку этот пример показывает, можно инициализировать элементы указателя функции CFTreeContext
структура к NULL
если Вы не хотите определять функции обратного вызова для контекста объекта CFTree.
Добавление Дерева к его Родителю
Чтобы иметь любое применение, объект CFTree должен быть вставлен в древовидную структуру; это должно быть помещено в иерархическое отношение к другим объектам CFTree. Чтобы сделать это, необходимо использовать одну из следующих функций CFTree для создания объекта дочерним элементом или одноуровневым деревом в связи с некоторым другим деревом:
CFTreeAppendChild
CFTreePrependChild
CFTreeInsertSibling
Перечисление 2 показывает дочернее дерево, добавляемое списку его родителя дочерних элементов.
Перечисление 2 , Добавляющее ребенка Кфтри к его родителю
/* assume anAddress and curTree already exist */ |
CFTreeRef child = FindTreeChildWithAddress(curTree, anAddress);if (NULL == child) { |
CFTreeContext ctx; |
child = CreateMyTree(CFGetAllocator(curTree)); |
CFTreeGetContext(child, &ctx); |
((MyTreeInfo *)ctx.info)->address = anAddress; |
CFTreeAppendChild(curTree, child); |
CFRelease(child); |
} |
Пример кода также иллюстрирует другой аспект интерфейса программирования CFTree. Иногда Вы, возможно, должны изменить определенные с помощью программы данные, связанные с уже создающимся объектом CFTree. Чтобы сделать это, вызовите CFTreeGetContext
функция на том объекте получить контекст дерева. Как только у Вас есть эта структура, можно получить доступ к определенным с помощью программы данным через info
указатель.
Получение дочерних деревьев
Тип CFTree имеет несколько функций, получающих дочерние деревья. Поскольку одноуровневые деревья находятся в последовательном порядке, Вы обычно используете только два из этих методов для пересечения дочерних деревьев одного родителя, CFTreeGetFirstChild
и CFTreeGetNextSibling
. Перечисление 3 показывает, как Вы делаете это.
Перечисление 3 , Пересекающее дочерние деревья семенного дерева
static CFTreeRef FindTreeChildWithAddress(CFTreeRef tree, UInt32 addr) { |
CFTreeRef curChild = CFTreeGetFirstChild(tree); |
for (; curChild; curChild = CFTreeGetNextSibling(curChild)) { |
CFTreeContext ctx; |
CFTreeGetContext(tree, &ctx); |
if (((MyTreeInfo *)ctx.info)->address == addr) { |
return curChild; |
} |
} |
return NULL; |
} |
Не весь CFTree функционирует действие на или дочерние деревья возврата. CFTreeGetParent
функция, например, получает семенное дерево данного дерева. CFTreeFindRoot
функция получает корневой объект CFTree текущей древовидной структуры — т.е. дерево структуры, не имеющей никакого семенного дерева.
Другие операции со структурами CFTree
Тип CFTree включает две функции, которые очень подобны другим функциям набора. CFTreeApplyFunctionToChildren
функция применяет определенную с помощью программы функцию applier к дочерним элементам родительского объекта CFTree. CFTreeSortChildren
функциональные виды дочерние элементы родительского объекта CFTree использование функции компаратора, которую можно определить (или использовать, пока оно соответствует CFComparatorFunction
введите).
Посмотрите, что Применение Определенных с помощью программы Функций к Наборам для использования детализирует подходящий для
CFTreeApplyFunctionToChildren
.Посмотрите Работу С Непостоянными Наборами для получения информации об использовании
CFArraySortValues
функция; большая часть этой информации применима кCFTreeSortChildren
функция.