2012-02-19 9 views
41

Estoy tratando de entender por qué existen objetos CF y NS, que parecen hacer lo mismo y son intercambiables mediante un puente sin cargo. Si, digamos, CFArray y NSArray hacen lo mismo, y puedo elegir entre ellos libremente, ¿cuál es el punto en ambos de existir? ¿Existen reglas generales sobre cuándo usar una sobre la otra? ¿Los objetos CF son solo objetos heredados de marcos antiguos? Cualquier idea sobre esto sería muy apreciada.Objetos CF vs objetos NS

+3

Debe tenerse en cuenta que a) no todos los tipos de CF tienen un NS equivalente y viceversa, yb) no todos los nombres que son iguales aparte del prefijo son de hecho "sin línea puente"; 'CFBundle' y' NSBundle', por ejemplo, no lo son.Más [en los documentos] (https://developer.apple.com/library/mac/documentation/General/Conceptual/CocoaEncyclopedia/Toll-FreeBridgin/Toll-FreeBridgin.html), como siempre. –

Respuesta

58

Para responder a sus preguntas en orden:

  1. Cuál es el sentido de los dos existentes? Hay unas pocas razones.

    Si desea proporcionar una API C, como la API de Carbon, y necesita elementos como matrices y diccionarios de objetos contados de referencia, desea una biblioteca como Core Foundation (que proporciona CFArray) y, por supuesto, necesita tener una API C

    Si desea escribir bibliotecas para que terceros puedan usar en Windows (por ejemplo), debe proporcionar una API de C.

    Si desea escribir una biblioteca de bajo nivel, digamos para interactuar con el kernel de su sistema operativo, y no desea la sobrecarga de la mensajería Objective-C, necesita una API C.

    Son buenas razones para tener Core Foundation, una biblioteca de C pura.

    Pero si desea proporcionar un nivel más alto, más agradable API en Objective-C, desea que los objetos de Objective-C que representan matrices, diccionarios, objetos de referencia-contado, y así sucesivamente. Entonces necesitas Foundation, que es una biblioteca de Objective-C.

  2. ¿Cuándo debería usar uno u otro? Generalmente, debe usar las clases Objective-C siempre que pueda, ya que la interfaz Objective-C es más agradable de usar: myArray.count (o) es más fácil de leer y escribir que CFArrayGetCount(myArray). Debe usar la API de Core Foundation solo cuando realmente lo necesite: cuando se encuentre en una plataforma que no tenga Objective-C, o cuando necesite funciones que la API de Core Foundation proporcione, pero que carezcan de los objetos de Objective-C. Por ejemplo, puede especificar devoluciones de llamada al crear un CFArray o un CFDictionary que le permiten almacenar objetos no contados por referencia. Las clases NSArray y NSDictionary no le permiten hacer eso; siempre asumen que está almacenando objetos contados por referencia.

  3. ¿Los objetos CF son solo objetos heredados? De ningún modo. De hecho, Nextstep existió durante años con solo la biblioteca Objective-C Foundation y ninguna biblioteca (pública) Core Foundation. Cuando Apple necesitó soportar tanto la API de carbono como la API de Cocoa en la parte superior de las mismas instalaciones de sistema operativo de nivel inferior, crearon (o hicieron público) la Fundación básica para admitir ambas.

Por cierto, algunos de los Fundamentos de la base son de código abierto. Puede encontrar la parte de código abierto para Mac OS X 10.10.5 aquí: https://opensource.apple.com/source/CF/CF-1153.18/. He encontrado que el código fuente de CFRunLoop y CFStream es muy informativo.

+0

Impresionante resumen, Rob. ¡Gracias! – Eric

1

CF significa CoreFoundation. Los objetos expuestos con CF en sus nombres son solo objetos regulares de Core Foundation, escritos en C. Todos los objetos son gratuitos con sus amigos de la Fundación Cocoa Touch en el terreno de Objective-C. Por lo general, son punteros opacos.

NS significa NextStep, que era el sistema operativo anterior en el que se basaba Mac OS X. Los objetos con prefijo NS generalmente se escriben enteramente en Objective-C o C o incluso algunos C++.

Realmente depende de lo que necesita que haga cada objeto. Ciertamente es más fácil para mí trabajar en Objective-C puro con NSString, entonces es para mí trabajar en una combinación de C y Objective-C con CFString, pero hay algunas cosas que los objetos de CF pueden hacer que los objetos de NS simplemente pueden ' t (principalmente cosas de muy bajo nivel). Los objetos CF también se interesan mucho más en las Ref, las mutaciones y las inspecciones que sus contrapartes NS.

(Para futuras referencias, existen algunos prefijos más: CG para CoreGraphics, UI para UIKit, QL para QuickLook, AV para AVFoundation, MP para MediaPlayer, MF para MessageFoundation, GL para GLKit y MK para MapKit) (Si me he perdido alguno, con mucho gusto lo editaré).

+2

Esta respuesta es básicamente correcta, pero puede crear cierta confusión. Core Foundation no "usa objetos basados ​​en Objective C". En algunos casos, los objetos Cocoa se implementan utilizando objetos de Core Foundation, pero nunca al revés. Las aplicaciones Cocoa deben vincular CoreFoundation.framework. Las aplicaciones de Core Foundation no tienen que vincular Foundation.framework (que proporciona NSString y sus amigos ObjC). Tampoco me referiría a CF como "objetos internos de Apple". Son una API pública completa y se usan comúnmente con otros frameworks Core como Core Text. Como dices, generalmente debes usar NS a menos que necesites CF. –

+0

Ediándolo ahora. THanks – CodaFi

+0

¿Qué quiere decir cuando dice que los objetos CF están asignados estáticamente? –

3

Hay algo de historia en esta pregunta. Core Foundation es el cerebro de la operación. Está escrito principalmente en C. Fue creado con la adquisición de NEXT y sus API por parte de Apple y les debe mucho. Las clases NS * a menudo son simplemente interfaces abstractas de Objective C construidas sobre los tipos CF *. Por lo tanto, cuando pregunta por qué existen CFArray y NSArray, la respuesta es que en realidad no lo hacen. NSArrays son CFArrays, NSStrings son CFStrings, etc. Es por eso que es posible establecer un puente sin cargo.

Para una lectura más interesante y detallada, me referiría a this blog post.

11

Core Foundation es una API C para una variedad de estructuras de datos comunes. La mayoría de estas estructuras de datos tienen equivalentes en Cocoa, pero no en todas. La mayoría de los que son equivalentes se conectan de forma gratuita, lo que les permite usarlos indistintamente, pero no todos.

El puente sin cargo es un truco de implementación muy inteligente. Si desea los detalles subyacentes, consulte el ridiculous_fish post que señala @Matt Wilding. Es el más autorizado sobre el tema (y una gran influencia en iOS:PTL capítulo 19 que también explica cómo funciona todo). Pero realmente no importa para la mayoría de los propósitos. Como señala Matt, generalmente puede pretender que un NSArray es lo mismo que un CFArrayRef. Esto no es cierto en muchos casos, pero a veces es cierto, y lo suficientemente cerca la mayoría del tiempo. Es lo mismo que decir que @"stuff" es lo mismo que NSString que contiene stuff. Es mayormente cierto, pero no exactamente.

Cuando OS 9 se movió a OS X, era muy conveniente proporcionar acceso C a estructuras de datos similares a Objective-C. Muchos frameworks de bajo nivel hoy exponen C API por motivos de rendimiento. No debe pensar en CF como "legado" o "interno". Debería considerarlo como de bajo nivel y solo debería usarlo cuando necesite la potencia que proporciona, o si se trata de un marco de bajo nivel que así lo requiera.

Los objetos CF a menudo son más flexibles que sus homólogos NS. Por ejemplo, CFDictionaryRef puede contener claves y valores que no son objetos, mientras que NSDictionary no puede. (Por supuesto, están libres de puente, por lo que puede crear un CFDictionaryRef no retenido y luego tratarlo como un NSDictionary. Tricky que ....)

Cuando Apple lanza nuevos marcos, notará que a menudo exponen C API primero, y luego agregan API Objective-C. Esta es una razón por la cual es una buena idea aprender Core Foundation, incluso si no la usa todos los días. Pero cuando sea posible, generalmente debería usar ObjC.

+0

Rob, gran explicación. Mencionaste un punto que pensé que era interesante. ¿Cuál es la diferencia entre @ "cadena" y NSString que contiene "cadena"? Pensé que @ "cadena" estaba en NSString implícito ... – Eric

+5

@ "cadena" es en realidad una '__NSCFConstantString', que es una subcategoría (tipo de) de' NSString'. ("Sort-of" porque es una clase de puente gratuita, que no es exactamente lo mismo que una subclase.) Las cadenas constantes están en el segmento __TEXT, no en el montón (junto con su cadena de caracteres subyacente, que se almacena por separado) e ignoran las llamadas 'retener' y' liberar'. –

Cuestiones relacionadas