Исходный код CoreFoundation общедоступен. В частности, для Snow Leopard код для CFRelease находится в http://www.opensource.apple.com/source/CF/CF-550/CFRuntime.c
. соответствующая часть выглядит следующим образом:
void CFRelease(CFTypeRef cf) {
if (NULL == cf) HALT;
#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
if (CF_IS_COLLECTABLE(cf)) {
if (CFTYPE_IS_OBJC(cf)) {
// release the GC-visible reference.
auto_zone_release(auto_zone(), (void*)cf);
} else {
// special-case CF objects for better performance.
_CFRelease(cf);
}
return;
}
#endif
}
Это не отвечает на ваш вопрос о мотивах проектирования, но вы также спросили, почему CFRelease не проверяет на NULL. Он проверяет и намеренно завершает работу, когда в качестве параметра передается NULL.
Мое личное убеждение похоже на мнение Куинна о том, что дизайнеры CF чувствовали, что передача значения NULL - ошибка программирования.
Все эти функции являются частью различных API, которые следуют различным соглашениям в отношении обработки NULL
:
CFRelease
является частью CoreFoundation C SDK, который не принимает NULL
ссылка в качестве аргументов по умолчанию. [nil release]
использует Objective-C (который допускает разыменование nil
) free(NULL)
является частью библиотеки C (libc
), которая допускает NULL
аргументы delete NULL
является частью библиотеки C ++ (libc++
), которая допускает NULL
аргументы Я думаю, авторы CoreFoundation
SDK решили быть более совместимыми с остальной частью SDK, а не с аналогичная функция в других SDK.
Хорошая идея, на первый взгляд, это не имеет особого смысла. Конечно, поведение должным образом задокументировано , но было бы неплохо, если бы оно могло корректно обрабатывать NULL
. Обратите внимание, что CFRetain
и CFMakeCollectable
(новое в 10.4, GC включен в 10.5) демонстрируют одинаковое поведение. Я не осведомлен обо всех мотивах, побудивших разработать его таким образом, но, вероятно, упор был сделан на внутреннюю согласованность с остальной частью структуры CoreFoundation.
Трудно / невозможно узнать , почему CF был разработан таким образом, если вы не можете спросить у одного из дизайнеров. Я предполагаю, что разработчики решили, что передача NULL для функций управления памятью является (должна быть?) Ошибкой программирования. Кто-то может возразить, что вызывание сбоя при NULL является желательным «безотказным» поведением, поскольку ошибки, которые приводят к сбою почти сразу же, легче отслеживать, чем ошибки, которые молча ничего не делают вместо того, что вы ожидаете. Лично я предпочитаю подход «ничего не делать с нулевым значением», но я думаю, что это жизнь ...
Учитывая, что API не может / не будет изменяться, вы можете либо проверить на NULL, либо обойти проблемный случай. . Одним из вариантов может быть определение встроенной функции или макроса, который вызывает CFRelease только для ссылок, отличных от NULL. В любом случае, вероятно, лучше указать в коде явное выражение, чтобы избежать путаницы в будущем.
Я предпочитаю подход «ничего не делать с нулевым значением», но я полагаю, что это жизнь ...Учитывая, что API не может / не будет изменяться, вы можете либо проверить значение NULL, либо обойти проблему. Одним из вариантов может быть определение встроенной функции или макроса, который вызывает CFRelease только для ссылок, отличных от NULL. В любом случае, вероятно, лучше указать в коде явное выражение, чтобы избежать путаницы в будущем.
Я предпочитаю подход «ничего не делать с нулевым значением», но я полагаю, что это жизнь ...Учитывая, что API не может / не будет изменяться, вы можете либо проверить значение NULL, либо обойти проблему. Одним из вариантов может быть определение встроенной функции или макроса, который вызывает CFRelease только для ссылок, отличных от NULL. В любом случае, вероятно, лучше указать в коде явное выражение, чтобы избежать путаницы в будущем.