Определите, что такое CFTypeRef? - PullRequest
8 голосов
/ 13 августа 2010

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

Ответы [ 3 ]

17 голосов
/ 13 августа 2010

CFGetTypeID():

if (CFGetTypeID(myObjectRef) == CFStringGetTypeID()) {
  //i haz a string
}
9 голосов
/ 13 августа 2010

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

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

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

  • Из-за бесплатной связи между Базовой основой и Фондом только потому, чтоCFTypeRef = CFStringRef не означает, что CFTypeRef ≡ CFStringRef, где = означает «равно», а означает «идентично».Существует различие, которое может быть или не быть важным в зависимости от контекста.Как предупреждение, это, как правило, там, где ошибки свободно перемещаются.

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

    Это очень важно отметить, что пока есть CFStringGetTypeID(), нет соответствующего CFMutableStringGetTypeID().

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

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

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

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

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

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

0 голосов
/ 25 сентября 2016

Если вы хотите узнать, какой тип CFTypeRef находится во время разработки, вы можете использовать следующий фрагмент:

printf("CFTypeRef type is: %s\n",CFStringGetCStringPtr(CFCopyTypeIDDescription(CFGetTypeID(myObjectRef)),kCFStringEncodingUTF8));

Это напечатает удобочитаемое имя для типа, чтобы вы знали, что этоявляется.Но Apple не гарантирует, что они будут поддерживать эти описания согласованными, поэтому не используйте это в рабочем коде.(Как и фрагмент будет утечка памяти, но вы все равно должны использовать его во время разработки, так что кого это волнует).

...