Red de conocimiento informático - Material del sitio web - Cómo compilar archivos arc compatibles con el proyecto mrc

Cómo compilar archivos arc compatibles con el proyecto mrc

Este ejemplo es muy simple. Esta es una aplicación para buscar cantantes. Contiene un UITableView simple y un cuadro de búsqueda. Cuando el usuario busca en el cuadro de búsqueda, se llama a la API MusicBrainz para completar la búsqueda y coincidencia de nombres. MusicBrainz es una plataforma abierta de información musical que proporciona servicios web XML gratuitos. Si está más interesado en MusicBrainz, puede visitar su sitio web oficial.

Se puede descargar aquí un ejemplo inicial de la demostración, que se describe brevemente aquí para comodidad de los nuevos usuarios. Abra el ejemplo descargado en Xcode y verá lo siguiente (los desarrolladores de Xcode e iOS deben omitir este párrafo)

AppDelegate.h/m Este es el delegado para toda la aplicación, nada especial es la entrada punto de cada programa iOS/Mac después de la función principal, y entra en el ciclo de vida de la aplicación. Aquí, el viewController inicial se cargará y se colocará en la ventana para su visualización. Además, appDelegate es responsable de manejar los eventos de delegados del sistema, como cuando el programa comienza a salir

MainViewController.h/m/xib Este es el ViewController principal para esta demostración y contiene un TableView y una barra de búsqueda. SoundEffect.h/m Clase simple que reproduce un efecto de sonido cuando MusicBrainz completa su búsqueda. punto de entrada del programa main.m, todos los programas c comienzan desde la función principal

AFHTTPRequestOperation.h/m Esto es parte del famoso marco de red AFNetworking, que se utiliza para ayudar a manejar las solicitudes de servicios de red de una manera sencilla. Esta es la única clase incluida aquí, no toda AFNetworking, ya que solo usamos esta clase. El código del marco completo se puede encontrar en la página correspondiente en github

SVProgresHUD.h/m/bundle es una barra de progreso de uso común que aparece durante la búsqueda, lo que indica que el usuario está buscando algo. Espere. Espera un momento. paquete es un paquete de recursos que contiene algunas imágenes utilizadas por esta clase. SVProgresHUD se puede encontrar aquí

Un vistazo rápido a la aplicación: MainViewController es una subclase de UIViewController, y el archivo xib correspondiente define el UITableView y UISearchBar correspondientes. Cuando el usuario busca, use AFHTTPRequestOperation para enviar una solicitud HTTP. Cuando se recibe la respuesta de MusicBrainz, los resultados se colocan en la matriz searchResult y se muestran con un TableView. Cuando el resultado devuelto está vacío, se muestra como no encontrado en el. Vista de tabla. La lógica principal está en el método -searchBarSearchButtonClicked: en MainViewController.m. Genera la URL de la consulta, reemplaza los encabezados de la solicitud según lo necesite MusicBrainz, completa la lógica de devolución y luego actualiza la interfaz de usuario en el hilo principal. Todo el procedimiento es relativamente sencillo. Todo el programa es relativamente simple~

Conversión automática de MRC a ARC

Volviendo al tema, ahora estamos discutiendo ARC, por lo que ignoraremos los detalles técnicos de REST API y Análisis XML por el momento... .. Todo el programa utiliza MRC para la gestión de la memoria, así que primero conviertamos esta demostración a ARC.

Básicamente, convertir a ARC significa eliminar todas las palabras clave de retención, liberación y liberación automática, por lo que antes de realizar la conversión, debemos aclarar algunos puntos:

* Xcode proporciona una herramienta de conversión automática ARC que puede ayudarlo a convertir el código fuente a ARC

* Por supuesto, también puedes realizar la conversión ARC tú mismo.

* También puedes especificar desactivar ARC para el código que no deseas convertir, lo que ayuda mucho con bibliotecas de terceros grandes y complejas que no se han convertido a ARC, ya que puedes fácilmente arruina el código que no escribiste....

En nuestra demostración usaremos las tres estrategias, solo para mayor claridad.

* Usaremos las tres estrategias, pero tenga en cuenta que esto es solo para demostrar cómo realizar conversiones. En la práctica, no tiene por qué ser tan problemático y la gran mayoría de los casos futuros deberían comenzar con la creación del proyecto.

En primer lugar, ARC es una característica del compilador LLVM 3.0, y es probable que los proyectos más antiguos (especialmente aquellos de la era Xcode 3) tengan GCC o LLVM-GCC como compilador predeterminado, por lo que el primero El paso es asegurarse de estar hablando con el compilador correcto. Seleccione el destino en el panel "Configuración del proyecto" y seleccione el compilador C/C/Objective-C en la "Configuración de compilación" para que sea Apple LLVM 3.0 o superior. Para asegurarse de que la conversión se realice sin problemas, personalmente recomiendo activar "Tratar advertencias como errores" y "Ejecutar analizador estático" para asegurarse de que el código no tenga advertencias o problemas de memoria después de cambiar los compiladores (es posible que el análisis estático no garantice esto, pero Algo es mejor que nada). OK ~ Pruébelo después de Limpiar (Shift Cmd K) Bulid, el proyecto de demostración modificado no tiene advertencias ni errores, lo cual es un buen comienzo. (Este es un buen comienzo. (Para el código con advertencias, este es un buen momento para solucionarlo...) Asegúrese de que no haya problemas de memoria en el código original antes de convertir).

El siguiente paso es completar la gran conversión de MRC a ARC. Aún en la página de configuración de compilación, cambie el Conteo automático de referencias de Objective-C a "Sí" (si no puede encontrarlo, mire la pequeña pestaña frente a la barra de búsqueda para ver si se ha cambiado a "Todos" " ...). Esta opción no se muestra en Básico), por lo que nuestro proyecto tendrá ARC habilitado en todo el código fuente. Luego... intenta compilar y verás, bueno... muchos errores.

Esto es normal, porque ARC no permite operaciones como devolución, liberación, etc., mientras que el código MRC definitivamente tendrá estas operaciones. Podemos corregir manualmente estos errores uno por uno, pero hacerlo es engorroso. Xcode nos proporciona una herramienta de conversión automática para ayudar a reescribir el código fuente, que solo requiere eliminar declaraciones redundantes y reescribir algunas palabras clave de atributos.

Este gadget es Edit-gt; Convertir a Objective-C ARC en Refactor. Después de hacer clic en él, nos permitirá elegir el archivo para convertir. Aquí, para ilustrar otros métodos además de la conversión automática. no convirtió todos los archivos, pero solo unos pocos (MainViewController..m y AFHTTPRequestOperation.m no se convirtieron). Tenga en cuenta que hay una señal de advertencia en el cuadro de diálogo que nos indica que el objetivo ya es ARC y, dado que hemos habilitado ARC en la configuración de compilación, Xcode habilitará ARC automáticamente para nosotros después de que completemos la conversión.

Después de hacer clic en "Verificar", recibimos la desafortunada noticia: no podemos completar la conversión y necesitamos resolver los problemas de preparación de ARC. Luego también nos dice que para ver todos los llamados problemas de preparación de ARC podemos ir a "Configuración" General. ", marque "Continuar construyendo después del error"... ¿Qué diablos? Bueno, ¡escuchemos primero lo que Xcode tiene que decir! Se recomienda utilizar "Cmd" y luego marcar "Continuar compilando en caso de error" antes de compilar.

El problema aún existe, pero deberías poder ver todo el código que causó el problema en el panel Problemas. En nuestro ejemplo, el problema ocurre en SoundEffect.m:

NSURL *fileURL = [[NSBundle mainBundle] URLForResource:filename withExtension:nil];

if (fileURL ! = nil)

{

SystemSoundID theSoundID;

OSStatus error = AudioServicesCreateSystemSoundID((CFURLRef)fileURL, amp.theSoundID);

if (error == kAudioServicesNoError)

soundID = theSoundID;

}

El código aquí intenta forzar un puntero NSURL a un puntero CFURLRef. Aquí hay algunos servicios principales involucrados, específicamente el contenido de la infraestructura central (CF). La función AudioServicesCreateSystemSoundID() acepta un CFURLRef como parámetro, que es un concepto de CF, pero lo que estamos construyendo en un nivel de abstracción superior es un objeto NSURL. En el marco Cocoa, hay muchas abstracciones desde objetos de nivel superior hasta objetos de nivel inferior, y cuando usamos estos dos objetos, a menudo podemos tratarlos de la misma manera sin distinción. Este tipo de objeto puede ser un "puente libre". objeto (teléfono gratuito puenteado). NSURL y CFURLRef son un buen ejemplo de un par de objetos básicos, donde CFURLRef y NSURL son en realidad intercambiables.

En términos generales, para garantizar la exactitud del código en el nivel más bajo, cuando se llama a API basadas en C en el desarrollo de iOS, generalmente se pasan en objetos CF, mientras que cuando se llama a API Objective-C, se pasan en NSObject pasado en el objeto. Por lo tanto, es necesario convertirlo al llamar a la API de C mediante el puente gratuito. Sin embargo, al compilar con ARC, el compilador necesita saber qué operaciones realizar en estos objetos puente por motivos de gestión de memoria. Si un objeto NSURL reemplaza a CFURLRef, ¿quién decide la desasignación de memoria y la destrucción fuera del alcance del objeto? Para resolver este problema, introdujimos las palabras clave bridge, bridge_transfer y __bridge_retained. En cuanto a qué palabra clave elegir para la conversión, debe decidirse en función del comportamiento real del código. Si está interesado en el mecanismo de puente gratuito, puede encontrar contenido relevante, como tipos aplicables, mecanismos internos, etc., y dar una breve introducción ~ Explicaré este tema con más detalle más adelante

Volver al demostración, ahora agregamos __bridge en el código anterior para convertirlo. Luego ejecute la herramienta de conversión ARC. Después de verificar que no hay problemas, comencemos la conversión. Por supuesto, habrá una interfaz de vista previa antes de la conversión real. Será mejor que verifiquemos aquí si la conversión se realiza como se esperaba. .

Estos cambios son relativamente simples, básicamente eliminan código innecesario y cambian los tipos de propiedades, por lo que no es necesario que los revise cada vez si está seguro, pero si es la primera vez que realiza una conversión ARC. , Te recomiendo que consultes estos cambios. Pero si es la primera vez que realiza la conversión ARC, le recomiendo que observe un poco los cambios para obtener una comprensión intuitiva de ARC. Échale un vistazo y lo entenderás... Una cosa a tener en cuenta es el cambio de autoreleasepool en main.m y la eliminación de [super dealloc] en todas las llamadas a dealloc, que también es el cambio principal de MRC a ARC...

Bien ~ construyamos después de que se complete la conversión... debería haber algunas advertencias. Para el atributo de retorno original, es más seguro convertirlo en un atributo fuerte, esto se hace automáticamente en LLVM 3.0, pero en 3.1, el atributo no es fuerte de forma predeterminada, por lo que habrá una advertencia al usar la asignación de atributos, por lo que Para agregar fuerte en la declaración de atributos. Entonces podría haber un problema en SVProgressHUD.m porque el autor original escribió el código de lanzamiento y otro código en una línea. Esto se debe a que el autor original escribió el código de lanzamiento y otro código en una línea. El autoconvertidor solo elimina partes del código, dejando partes que no deberían estar allí.

La historia después de la conversión automática

Luego compila nuevamente, sin errores ni advertencias, genial ~ espera... Simplemente no manejamos MainViewController y AFHTTPRequestOperation, ¿verdad? Entonces debería haber algo así como liberación en estos dos archivos, ¿verdad? Si observa estos dos archivos, encontrará que contienen varias versiones, pero ¿por qué se pueden compilar? Es obvio que hay muchos errores antes de la conversión automática... La respuesta es simple, porque no verificamos estos dos archivos durante la conversión automática, por lo que el compilador marcó estos dos archivos como "no relacionados" después de la conversión automática. conversión Compilar con ARC". Puede ver que en la fase de compilación del objetivo, MainViewController.m y AFHTTPRequestOperation.m están marcados con el indicador -fno-objc-arc, lo que significa que estos dos archivos no se compilarán utilizando las reglas ARC.

La razón para usar este indicador de compilación es obvia, ya que siempre habrá algún código de terceros que no se haya convertido a ARC (tal vez debido a la pereza del mantenedor o porque el mantenedor ha quedado obsoleto). y para poder completar la conversión rápidamente, es mejor deshabilitar el uso de ARC en dicho código aplicando el indicador -fno-objc-arc.

Para facilitar la búsqueda, la siguiente es una lista de problemas que pueden ocurrir durante el proceso de conversión. Debemos prestar atención para evitar estos problemas en el código al usar ARC:

" Elenco... requiere un yeso puenteado"