Определение, каков CFTypeRef?

У меня есть функция, которая возвращает CFTypeRef. Я понятия не имею, каково это действительно. Как я определяю это? Например, это мог бы быть CFStringRef.

9
задан Kristina Brooks 12 August 2010 в 20:57
поделиться

2 ответа

CFGetTypeID () :

if (CFGetTypeID(myObjectRef) == CFStringGetTypeID()) {
  //i haz a string
}
18
ответ дан 4 December 2019 в 07:46
поделиться

Короткий ответ: вы можете (см. Ответ Дэйва Делонгса). Длинный ответ: вы не можете. Оба верны. Лучше спросить: «Зачем вам это нужно?». На мой взгляд, если вы можете организовать вещи так, чтобы вам не нужно было знать, вам, вероятно, будет лучше.

Я не говорю, что вы не можете этого делать или даже не должны. Я говорю о том, что есть некоторые скрытые подводные камни, когда вы начинаете идти по этому пути, и иногда вы действительно не знаете, каковы все неустановленные предположения. К сожалению, правильное программирование зависит от знания всех мелких деталей. Внезапно, вот несколько потенциальных ошибок:

  • Насколько мне известно, набор типов Core Foundation увеличивался с каждым основным выпуском ОС. Поэтому каждый основной выпуск ОС имеет надмножество типов Core Foundation предыдущих выпусков и, вероятно, строгое надмножество при этом. Это «наблюдаемое поведение», а не обязательно «гарантированное». Важно отметить, что «вещи могут меняться и меняются», и при прочих равных, более легкие и простые решения, как правило, не принимают это во внимание. Обычно считается плохим стилем программирования кодировать что-то, что ломается в будущем, независимо от причины или оправдания.

  • Из-за бесплатного соединения между Core Foundation и Foundation только потому, что CFTypeRef = CFStringRef не означает, что CFTypeRef ≡ CFStringRef , где = означает «равно», а означает «идентично». Есть различие, которое может быть или не иметь значения в зависимости от контекста. В качестве предупреждения, здесь, как правило, беспрепятственно бродят ошибки.

    Например, CFMutableStringRef может использоваться везде, где может использоваться CFStringRef , или CFStringRef = CFMutableStringRef . Однако вы не можете использовать CFStringRef везде, где можно использовать CFMutableStringRef по очевидным причинам. Это означает CFStringRef ≢ CFMutableStringRef . Опять же, в зависимости от контекста, они могут быть равными, но не идентичными.

    Очень очень важно отметить, что хотя существует CFStringGetTypeID () , нет соответствующего CFMutableStringGetTypeID () .

  • Логически CFMutableStringRef является строгим надмножеством CFStringRef . Из этого следует, что передача добросовестного неизменяемого CFStringRef в вызов API CFMutableString вызовет «своего рода проблему». Хотя сейчас это может быть не так (например, 10.6), я точно знаю, что в прошлом было верно следующее: вызовы API CFMutableString не проверяли, что «строковый аргумент» действительно изменяемый (это действительно было верно для всех типов, которые сделали различие между неизменяемым и изменяемым). Проверки были, но они были в форме утверждений отладки, которые были отключены в сборках «Release» (другими словами, проверки никогда не выполнялись на практике).

    Это (или, возможно, было) официально не считается ошибкой, и ( тривиальная ) проверки изменчивости не выполнялись «по соображениям производительности». Не предоставляется никакого «общедоступного» API для определения изменчивости указателя CFString (или изменчивости любого типа). В сочетании с бесплатным мостом это означало, что вы могли изменять неизменяемые объекты NSString , даже несмотря на то, что API NSMutableString выполняли проверку изменчивости и вызывали «некую проблему» при попытке изменить неизменяемый объект. Приправьте тем фактом, что константные строки @ "" в вашем источнике отображаются в постоянную память во время выполнения.

    Официальной линией, насколько я помню, было «не передавать неизменяемые объекты, CFStringRef или NSString, в API CFMutableString, и более того, это было ошибкой».Когда было указано, что с этой позицией могут быть некоторые проблемы, связанные с безопасностью (не говоря уже о том факте, что это было принципиально невозможно), скажем, если что-нибудь когда-либо допустило ошибку критической зависимости от неизменности строки, особенно "хорошо известной" строк, ответ был «проблема теоретическая, и в данный момент ничего не будет сделано, пока не будет продемонстрирован работоспособный эксплойт».

    Обновление: Мне было любопытно узнать, каково текущее поведение. На моем компьютере, работающем под управлением 10.6.4, с использованием API CFMutableString на неизменяемом CFString , неизменяемая строка становится по существу @ "" , что, по крайней мере, лучше чем то, что было раньше (<= 10,5)и фактически измените строку. Определенно не идеальное решение, но имеет тот горький привкус реального мира, где его единственным достоинством является то, что это «наименее худшее решение».

Так что помните, будьте осторожны в своих предположениях! Вы можете это сделать, но если вы это сделаете, более важно, чтобы вы не сделали это неправильно . :) Конечно, много «неправильных» решений будут работать, поэтому тот факт, что что-то работает, не обязательно является доказательством того, что вы делаете это правильно. Хорошие времена!

Кроме того, в системе Duck Typed часто считается дурным тоном и, возможно, даже ошибкой, «слишком внимательно присматриваться к типу объекта». Objective-C определенно является системой с утиным типом, и это, несомненно, распространяется и на Core Foundation из-за тесной связи между Toll-Free мостом. CFTypeRef является прямым проявлением этой неоднозначности типа утки и, в значительной степени, в зависимости от контекста, может быть явным способом сказать: «Вы не должны слишком внимательно смотреть на типы».

9
ответ дан 4 December 2019 в 07:46
поделиться
Другие вопросы по тегам:

Похожие вопросы: